grep 如何返回不同數量的匹配項?
我需要將一個文件(24 行)grep 成兩個文件(有點大)。
原始文件包含 24 行類似於此字元串:
AATGGACGCTTAAC[A|C|T][A|C|G]CGGC[A|T]TCGGAT
我執行以下操作:
grep -f aList hugeFile_N*.csv | wc -l 4396868
然後,為了仔細檢查一切是否正常,我將文件分成兩個文件,並通過另一個 grep 使用它們:
cat aList | head -n 12 > firstHalf cat aList | tail -n +13 > secondHalf grep -f firstHalf hugeFile_N*.csv | wc -l 2169008 grep -f secondHalf hugeFile_N*.csv | wc -l 2228046
現在,我期望來自兩個單獨的 grepped 文件的匹配總數將等於我為原始文件找到的匹配數。但是,如您所見:
2169008 + 2228046 = 4397054 4397054 != 4396868
不是這種情況。我們有 186 場比賽失去。這裡發生了什麼?
我還對(實際上非常簡單的)文件進行了一些調查。在這裡,我從兩個單獨的部分 grep 的結果:
grep -f <(cat firstHalf secondHalf) hugeFile_N*.csv > together
然後我分別 grep 兩半:
grep -f firstHalf hugeFile_N*.csv > separately grep -f secondHalf hugeFile_N*.csv >> separately
而且,如前所述,匹配的數量是不同的:
wc -l together 4396868 together wc -l separately 4397054 separately
但是,唯一匹配的數量是相同的:
sort -u together | wc -l 3735836 sort -u separately | wc -l 3735836
有趣的是,如果我 grep 原始文件中的兩半,我根本沒有匹配項。我想知道為什麼會這樣:
grep -f ../code/firstHalf ../code/aList | wc -l 0 grep -f ../code/secondHalf ../code/aList | wc -l 0
我 100% 確定兩半都存在,
aList
因為我可以用我的編輯器看到它(它們每行 12 行,所以肉眼甚至不難看到)。我覺得我做錯了
grep
什麼但是……什麼?裡面的所有線條
aList
都是獨一無二的。
grep
只查找至少匹配給定模式之一的行。中的24 個模式aList
,可能前半場中的一個和後半場中的一個匹配。這意味著您將在同一行上獲得 和 的匹配grep -f firstHalf
項grep -f secondHalf
。分別執行模式列表的兩半會加倍計算這些行。例如
$ cat test.txt abc foo bar foobar $ cat patterns foo bar $ grep -c -f patterns test.txt 3
但當然還有:
$ grep -c -e foo test.txt 2 $ grep -c -e bar test.txt 2
並且 2+2 > 3。
如果所有行都不同,那麼計算唯一匹配行當然是消除這種影響的一種方法。您可以使用
grep -n
將行號添加到輸出中,使每個輸出行都是唯一的。當然請記住,預設情況下grep
會在行中的任何位置查找匹配項,如果這不是您想要的,您需要使用grep -x
.另請注意,這意味著
[A|C|T]
匹配任何字元A
、或。如果您不想或不需要匹配管道字元,請使用. 或者,如果您需要交替,則必須使用擴展的正則表達式 ( ),然後(帶括號,而不是括號)。但這不是必需的,只要所有替代項都是單個字元。C``T``|``[ACT]``grep -E``(this|that)