Text-Processing
使用 sed 剪切並添加到 diff 輸出的特定行
我將兩個目錄之間的 diff 命令的輸出儲存在一個名為
differenceOutput.txt
.So中目前只有兩種行,
differenceOutput.txt
所有行都有格式A或B,其中A和B如下所示:一個)
Only in /tmp/__tmp_comp206_alex/test_files/: file_1.txt
二)
Files /tmp/__tmp_comp206_alex/test_files/file_3.conf and /tmp/__tmp_comp206_alex/diff_dir/file_3.conf differ
使用
sed
,我想將differenceOutput.txt
格式 A 的所有行更改為格式 C,並將格式 B 的所有行更改為格式 D,其中 C 和 D 如下所示:C)
/tmp/__tmp_comp206_alex/test_files/file_1.txt is missing
D)
/tmp/__tmp_comp206_alex/diff_dir/file_3.conf differs
我該怎麼做
sed
?超級混淆 sed 語法。我花了幾個小時試圖弄清楚這一點,但無法對此做出正面或反面。有人可以幫幫我嗎?
$ awk ' sub(/^Only in /,"") { sub(/: /,""); $0=$0 " is missing" } sub(/^Files /,"") { sub(/ and .*/,""); $0=$0 " differs" } 1' differenceOutput.txt /tmp/__tmp_comp206_alex/test_files/file_1.txt is missing /tmp/__tmp_comp206_alex/test_files/file_3.conf differs
這假設您的目錄名稱不包含
:<blank>
or<blank> and <blank>
並且您的文件/目錄名稱都不包含換行符。以上是使用從您在問題中提供的範例輸入創建的文件進行測試的:
$ cat differenceOutput.txt Only in /tmp/__tmp_comp206_alex/test_files/: file_1.txt Files /tmp/__tmp_comp206_alex/test_files/file_3.conf and /tmp/__tmp_comp206_alex/diff_dir/file_3.conf differ
幹得好。兩個直接
sed
替換a='Only in /tmp/__tmp_comp206_alex/test_files/: file_1.txt' b='Files /tmp/__tmp_comp206_alex/test_files/file_3.conf and /tmp/__tmp_comp206_alex/diff_dir/file_3.conf differ' printf "%s\n%s\n" "$a" "$b" | sed -e 's!^Only in \([^:]*\)/: \(.*\)!\1/\2 is missing!' -e 's!^Files .* and \(.*\) differ$!\1 differs!'
輸出
/tmp/__tmp_comp206_alex/test_files/file_1.txt is missing /tmp/__tmp_comp206_alex/diff_dir/file_3.conf differs
解釋
- 我已經使用
!
而不是作為配方/
中的分隔符,否則我們將不得不轉義匹配和替換字元串中的每一次出現sed``s/match/replacement/``/
- 匹配部分中的替換匹配轉義括號表達式(即)中的
\1
and\2``\(...\)
最大的假設是您的文件名不包含
diff
輸出中的冒號和其他匹配的單詞。輸出充其量是脆弱的diff
,您最好滾動自己的循環find
並cmp -s
直接產生所需的輸出。(這將是我對穩健解決方案的偏好。)#!/bin/bash src='/tmp/__tmp_comp206_alex/test_files' dst='/tmp/__tmp_comp206_alex/diff_dir' ( cd "$src" && find -type f -print0 ) | while IFS= read -r -d '' item do if [[ ! -f "$dst/$item" ]] then printf "%s is missing\n" "$dst/$item" elif ! cmp -s "$src/$item" "$dst/$item" then printf "%s differs\n" "$dst/$item" fi done