Text-Processing

使用 sed 剪切並添加到 diff 輸出的特定行

  • October 9, 2020

我將兩個目錄之間的 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/``/
  • 匹配部分中的替換匹配轉義括號表達式(即)中的\1and\2``\(...\)

最大的假設是您的文件名不包含diff輸出中的冒號和其他匹配的單詞。輸出充其量是脆弱的diff,您最好滾動自己的循環findcmp -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

引用自:https://unix.stackexchange.com/questions/613745