Text-Processing

如何使用 Diff 命令忽略一行中的文本並根據條件獲取不匹配的數據

  • March 20, 2017

我正在嘗試使用給定的輸入獲得以下輸出。這可以通過diff命令完成嗎?我正在嘗試這種語法但不工作:

diff -a  --suppress-common-lines a.txt b.txt

這是兩個輸入文件:

首先a.txt

abc abc/d_4.1/efg 35 
xyz abc/d_4.1/efg 36
mno abc/d_4.1/efg 38

並且b.txt

abc abc/d_4/efg 35
xyz abc/d_4/efg 36
mno abc/d_4/efg 40

我需要這個輸出(下面是與兩個文件diff無關的):d_4.1``d_4

mno abc/d_4.1/efg 38
mno abc/d_4/efg  40

實用程序diff沒有跳過欄位的選項。

我試圖讓它與 cut & uniq 一起工作。認為下面會起作用,輸出中將缺少第 2 列。

$ cut -d/ -f1,3 file1 file2 |sort |uniq -u  #column 2 is skipped

作為更正確的解決方案,我提出以下 awk:

awk -F" |/" '{a=$1$2$4$5;seen[a]++;out[a]=$0}END{for (i in seen) if (seen[i]==1) print out[i]}' file1 file2

我使用空格或斜杠 / 欄位分隔符,因為您給出的輸入數據在每行末尾包含一些額外的空格。

即使您的真實數據不包含額外的空白,上述解決方案仍然可以正常工作。

awk 的邏輯如下:它模擬 uniq -u ,跳過中間列 ( /d_4/)。

它只列印 file1 和 file2 之間的所有唯一行(由 awk 連接)。

測試(另見線上測試

cat file1 
cat file2 
echo "awk start:"
awk -F" |/" '{a=$1$2$4$5;seen[a]++;out[a]=$0}END{for (i in seen) if (seen[i]==1) print out[i]}' file1 file2
echo "awk end"

#Output
#file1            
abc abc/d_4.1/efg 35
xyz abc/d_4.1/efg 36 
mno abc/d_4.1/efg 38
#file2
abc abc/d_4/efg 35
xyz abc/d_4/efg 36 
mno abc/d_4/efg 40

awk start:      
mno abc/d_4/efg 40
mno abc/d_4.1/efg 38
awk end

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