숫자 열이 포함된 두 파일에서 일치하는 줄을 인쇄합니다.

숫자 열이 포함된 두 파일에서 일치하는 줄을 인쇄합니다.

나는 다음을 수행하려고 노력했습니다.

  • 3개의 숫자 열이 있는 파일이 있고 1개의 숫자 열이 있는 더 작은 파일과 비교하여 일치하는 행을 인쇄하고 싶었습니다.
  • 나는 사용하고 있지만 grep -F항상 일치하지 않는 행을 제공합니다.

답변1

내 생각엔 101더 작은 파일이 포함될 때 10일치하는 것과 같은 것을 보게 될 것입니다. 이는 10이 101의 하위 문자열이기 때문입니다.

기본 파일에 필드가 하나만 있는 경우 -x정확한 일치를 위해 grep 옵션을 사용할 수 있습니다. 예를 들어

grep -x -F -f smallerfile.txt mainfile.txt

3개의 필드가 있기 때문에 각 필드를 개별적으로 일치시켜야 하므로 perl이나 awk 같은 것을 사용해야 합니다. 예를 들어 awk를 사용하면 다음과 같습니다.

$ cat smallerfile.txt 
1
10
25
152

$ cat mainfile.txt 
1 2 3
5 10 15
10 11 12
100 101 102
150 151 152
250 255 260

$ awk 'FNR == NR { nums[$1]++ ; next }
       $1 in nums || $2 in nums || $3 in nums' smallerfile.txt mainfile.txt
1 2 3
5 10 15
10 11 12
150 151 152

그런데 세 개 이상의 필드를 확인해야 하면 스크립트를 작성하거나 업데이트하는 것이 지루해집니다. 이를 방지하려면 각 필드(수에 관계없이)를 반복하고 그 중 하나의 값이 배열에 있는지 확인하는 awk 함수를 작성할 수 있습니다 nums. 예를 들어

$ awk 'function check_all_fields() {
         for (i=1; i<=NF; i++) {
           if ($i in nums) return 1
         }
         return 0
       }
       FNR == NR { nums[$1]++ ; next }
       check_all_fields()' smallerfile.txt mainfile.txt
1 2 3
5 10 15
10 11 12
150 151 152

보시다시피 출력은 첫 번째 버전과 동일합니다.

check_all_fields()함수가 입력 행에서 일치하는 필드를 확인하면 1(true)을 반환합니다. 현재 행에 1이 전혀 표시되지 않으면 0(false)을 반환합니다.

답변2

우리는 이웃을 활용하여 검색 문자열을 sed안내 하는 다음 접근 방식을 사용하여 이를 수행할 수 있습니다.grep

sed -e 's/.*/\\<&\\>/' f1 | grep -Ef - f3col

산출:-

1 2 3
5 10 15
10 11 12
150 151 152

awk그림과 같이 조작 할 수 있습니다. 먼저 a[...]단일 열 파일의 열을 기준으로 하는 연관 배열을 형성합니다. 그런 다음 3열 파일의 각 행에서 플래그를 초기화 p하고 단일 열 파일의 필드와 일치하는 데이터가 있으면 플래그를 증가시킵니다. 그런 다음 for 루프가 끝날 때 플래그가 적어도 한 번 증가하면 조건부로 레코드를 인쇄합니다.

awk '
NR==FNR{a[$1];next}
{
  for (p=i=1; i<=NF; i++) if ($i in a) p++
}p>1
' f1 f3col

python데이터 구조 자체는 set아래와 같이 집합의 교집합이 비어 있지 않은 경우를 인쇄하는 구현을 지원합니다.

python3 -c 'import sys
file1,file2 = sys.argv[1:]

with open(file1) as f1, open(file2) as f2:
  s1 = { _.rstrip() for _ in f1 }
  for _ in f2:
    s2 = set(_.rstrip().split())
    if bool(s2 & s1):
      print(_,end="")
' f1 f3col

구문을 사용하여 POSIX sed먼저 단일 열 파일을 사용하여 POSIX sed 코드를 생성한 다음 이를 3열 파일에 적용합니다.

sed -e '
  h;G;G
  s/.*/^&$/
  s|\n| /b&/ |g
  s|.*|/&/b|;$a\
d
' f1 | sed -f - f3col

perl이 작업은 여러 가지 방법으로 수행할 수 있습니다.

perl -lane '
  @A || chomp(@A=<STDIN>);
  for my $f (@F) {
    print,last if grep { $f == $_ } @A;
  }
' f3col < f1

perl -MList::Util=any -lane '
  chomp(@A=<STDIN>) if !@A;
  print if 
    any {
      my $f = $_;
      any { $_ == $f } @A;
    } @F;
' f3col < f1

관련 정보