Linux
存在於一個文件中但不存在於另一個文件中的 grep 行
我正在嘗試做簡單的事情
grep
,grep -v
所以我會從中得到a.txt
那些存在於b.txt
而不是c.txt
.3 個文件的範例
a.txt
:a b c d e
up.txt
:a.up b.up c.up
dw.txt
:a.dw b.dw
期望的輸出:
c
我寫了下面的程式碼,但
grep
看起來$(sed...)
一次是一行,而不是一個整體:sed 's/.up//' /tmp/b.txt | grep -f /tmp/a.txt | grep -vf $(sed 's/.dw//' /tmp/c.txt)
假設所有文件都已排序,並且我們使用的 shell 可以理解程序替換(如
bash
):$ join -t . -v 1 -o 0 <( join -t . a.txt b.txt ) c.txt c
或者,對於其他貝殼,
$ join -t . a.txt b.txt | join -t . -v 1 -o 0 - c.txt c
這使用
join
兩次來執行文件之間的關係連接。數據被解釋為以點分隔的欄位(帶有-t .
)。
a.txt
和之間的連接b.txt
是直截了當的,產生a.up b.up c.up
這些是兩個文件中的所有行,其第一個點分隔欄位出現在兩個文件中。輸出由連接欄位 (
a
,b
,c
) 組成,後跟來自兩個文件的其他欄位(只有b.txt
任何進一步的數據)。第二個連接有點特別。
-v 1
我們要求查看第一個文件(上面的中間結果)中不能與第二個文件中的任何行配對的條目,c.txt
. 此外,我們只要求查看連接欄位本身 (-o 0
)。沒有-o
標誌,我們將得到c.up
結果。如果文件未排序,則文件名的每次出現
file
都可以<( sort file )
在命令中替換為。
使用單個快速 GNU**
awk
**命令:awk -F'.' \ '{ if (ARGIND == 1) a[$1]; else if (ARGIND == 2 && $1 in a) comm[$1]; else if (ARGIND == 3){ delete a; if ($1 in comm) delete comm[$1] } } END{ for (i in comm) print i }' a.txt b.txt c.txt
輸出:
c
-F'.'
-.
視為欄位分隔符ARGIND``ARGV
-正在處理的目前文件(命令行參數數組)中的索引comm
-前 2 個文件 (和)之間的公共項目數組a.txt``b.txt