2016-10-26 56 views
0

我比較是產生像這樣包列於兩個TSV文件:TSV之間的差異顯示由

rpm -qa --qf "%{name}\t%{version}\t%{license}\n" | sort -n > packages 

這生成一個製表符分隔文件,例如:

alsa-firmware 1.0.28 GPL+ and BSD and GPLv2+ and GPLv2 and LGPLv2+ 
alsa-lib  1.0.28 LGPLv2+ 
alsa-tools-firmware  1.0.27 GPLv2+ 

在另一系統我運行相同的命令,其中安裝了相當多的軟件包。我想要第二臺服務器上的附加軟件包列表。這裏棘手的部分是我希望匹配列表不要按版本過濾。 Comm和Diff檢查整個行,我只想過濾第一個「列」。

例如,如果第二個服務器具有以下軟件包列表:

acl  2.2.51 GPLv2+ 
alsa-firmware 2.0.28 GPL+ and BSD and GPLv2+ and GPLv2 and LGPLv2+ 
alsa-lib  2.0.29 LGPLv2+ 
alsa-tools-firmware  2.0.27 GPLv2+ 
audit 2.4.1 GPLv2+ 
binutils  2.23.52.0.1  GPLv3+ 

我正在尋找一個命令(SED,AWK,通訊,DIFF等)將由第一回的區別列 - 在這種情況下將是:

acl  2.2.51 GPLv2+ 
audit 2.4.1 GPLv2+ 
binutils  2.23.52.0.1  GPLv3+ 

注意ALSA包已經改變了版本,但仍然有相同的包名。

回答

1

awk,在這兩個文件

$ awk 'NR==FNR{a[$1]; next} !($1 in a)' file1 file2 
acl  2.2.51 GPLv2+ 
audit 2.4.1 GPLv2+ 
binutils  2.23.52.0.1  GPLv3+ 


或者通過第一列作爲搜索模式grep只匹配第一列。這是假設在file2其他列將不與搜索項

$ awk '{print $1}' file1 | grep -vFf - file2 
acl  2.2.51 GPLv2+ 
audit 2.4.1 GPLv2+ 
binutils  2.23.52.0.1  GPLv3+ 


sed,類似於grep解決方案,但容易出錯,如果匹配的file1第一列包含任何正則表達式元字符

$ sed -f <(sed -E 's|^(\S+).*|/\1/d|' file1) file2 
acl  2.2.51 GPLv2+ 
audit 2.4.1 GPLv2+ 
binutils  2.23.52.0.1  GPLv3+ 
+1

第一個命令awk本身是正確的方法,但'++'除了使用循環外什麼也不做。不應該使用awk + ​​grep,因爲它會錯誤地比較/匹配整行而不是第一個字段,並且應該避免出於您陳述的原因和其他原因嵌套的seds。 –

+1

@EdMorton謝謝,我不知道'a [$ 1]'就夠了:) – Sundeep

+0

偉大的工作傢伙! awk的確給了我想要的結果。 – user3063045