grep 如何返回不同数量的匹配项?

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

现在,我期望两个单独 grep 文件的匹配总数将等于我为原始文件找到的匹配数量。但是,正如你所看到的:

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都是独一无二的。

答案1

grep只查找匹配的行最后一个给定的模式。中的 24 个模式中aList,前半部分的一个和后半部分的一个可能匹配。这意味着您将在同一行上获得 和 的匹配grep -f firstHalfgrep -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]意味着匹配任何字符AC或。如果您不想或不需要匹配管道字符,请仅使用。或者,如果您需要交替,则必须使用扩展正则表达式 ( ),然后(带括号,而不是方括号)。但只要所有替代字符都是单个字符,那就没有必要。T|[ACT]grep -E(this|that)

相关内容