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 -f <(cat firstHalf secondHalf) hugeFile_N*.csv > together

그런 다음 두 부분을 별도로 파악합니다.

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전반부에 1개, 후반부에 1개가 일치할 수 있습니다. 이는 동일한 라인에서 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)

관련 정보