Unix와 Awk를 사용하여 한 파일에서는 줄을 찾았지만 다른 파일에서는 찾을 수 없습니다.

Unix와 Awk를 사용하여 한 파일에서는 줄을 찾았지만 다른 파일에서는 찾을 수 없습니다.

7개의 필드가 있는 2개의 파일이 있고 field1과 field2를 기반으로 file1에는 있지만 file2에는 없는 줄을 인쇄하고 싶습니다.

논리: 특정 열1과 열2가 있는 모든 행을 인쇄하고 싶습니다. 그리고 file2에서 컬럼1과 컬럼2의 컬렉션을 찾지 못했습니다. 예: "sc2/10 10" 이 세트는 파일 2에서 볼 수 없으므로 출력으로 인쇄됩니다.

파일 1:

sc2/80         20      .        A       T         86       F=5;U=4
sc2/60         55      .        G       T         76       F=5;U=4
sc2/10         10      .        G       C         50       F=5;U=4
sc2/68         20      .        T       C         71       F=5;U=4
sc2/24         24      .        T       G         31       F=5;U=4
sc2/11         30      .        A       T         60       F=5;U=4

파일 2:

sc2/80         20      .        A       T         30       F=5;U=4 
sc2/60         55      .        T       T         77       F=5;U=4 
sc2/68         20      .        C       C         01       F=5;U=4
sc2/24         29      .        T       G         31       F=5;U=4
sc2/24         19      .        G       G         11       F=5;U=4
sc2/88         89      .        T       G         51       F=5;U=4

예상 출력:

sc2/10         10      .        G       C         50       F=5;U=4 
sc2/11         30      .        A       T         60       F=5;U=4 

귀하의 도움에 감사드립니다.

답변1

입력이 크지 않으면 file2쌍을 해시에 저장하고 이를 사용하여 file1.

awk 'FNR == NR { h[$1,$2]; next }; !($1 SUBSEP $2 in h)' file2 file1

산출:

sc2/10         10      .        G       C         50       F=5;U=4         
sc2/24         24      .        T       G         31       F=5;U=4
sc2/11         30      .        A       T         60       F=5;U=4

IIUC가 sc2/24 24출력에 올바르게 포함됩니다.

설명하다

  • FNR == NR { h[$1,$2]; next }쌍을 해시 $1/$2에 저장합니다 h(아래 첨자를 통해 배열에 액세스하면 할당하기에 충분합니다). 하지만 첫 번째 입력 파일( file2)에서만 가능합니다. 이 next명령은 다음 레코드로 이동합니다.
  • ! ($1 SUBSEP $2 in h)해당 줄의 기본 블록 만 file1평가되고 호출됩니다.아니요$1/$2쌍이 포함되어 있습니다 . 기본 블록은 입니다 { print $0 }. (참고: 할당되므로 !h[$1,$2](와 동일 )을 사용하지 마십시오.)!h[$1 SUBSEP $2]

위의 내용은 파일의 처음 두 필드에서 찾을 수 없는 값 SUBSEP(일반적으로 문자) 을 가정합니다.^\

답변2

grep -Fvxf <remove> <all-lines>

  • 정렬되지 않은 파일과 함께 작동
  • 질서 유지
  • POSIX입니다

예:

cat <<EOF > A
b
1
a
0
01
b
1
EOF

cat <<EOF > B
0
1
EOF

grep -Fvxf B A

산출:

b
a
01
b

설명하다:

  • -F: 기본 BRE 대신 리터럴 문자열을 사용합니다.
  • -x: 전체 라인과 일치하는 일치 항목만 고려
  • -v: 인쇄 불일치
  • -f file: 주어진 파일에서 패턴을 가져옵니다.

이 방법은 더 일반적이기 때문에 미리 정렬된 파일에 대한 다른 방법보다 속도가 느립니다. 속도도 중요한 경우 다음을 참조하세요.https://stackoverflow.com/questions/18204904/fast-way-of-finding-lines-in-one-file-that-are-not-in-another

관련 정보