파일에서 누락된 줄을 찾으려면 다음 awk 명령을 알아야 합니다.

파일에서 누락된 줄을 찾으려면 다음 awk 명령을 알아야 합니다.

다음 awk명령 1.txt2.txt.

awk 'NR==FNR{b[$0]=1;next}!b[$0]' 1.txt 2.txt

awk이 구성이 누락된 행을 찾는 방법을 단계별로 살펴봐야 합니다 .

답변1

스크립트는 첫 번째 파일에 나타나지 않는 두 번째 파일의 모든 줄을 출력합니다.

awk 'NR==FNR { b[$0] = 1; next } !b[$0]' 1.txt 2.txt

스크립트 는 awk먼저 . 현재 레코드를 포함하여 지금까지 읽은 레코드(행)의 총 개수입니다. 읽은 레코드 수입니다.NRFNRNRFNR현재의입력 파일. 이 두 숫자가 같다면 우리는 여전히 읽고 있는 것입니다.첫 번째입력 파일. 충돌이 발생합니다.첫 번째 파일이 다음과 같은 경우비어 있는NR == FNR두 번째 파일도 마찬가지입니다.

첫 번째 입력 파일을 읽는 경우(비어 있지 않다고 가정) b[$0] = 1현재 레코드의 내용이 해시 키로 사용되며 해당 키 1의 값은 배열에 저장됩니다 b(배열 인덱스는 awk에서 문자열이 됩니다 . 그런 다음 스크립트가 실행됩니다 next. 즉, 스크립트의 시작 부분으로 돌아가서 다음 레코드를 읽습니다.

NR경우아니요같음 FNR, 그러면 이는 우리가 읽고 있다는 뜻입니다.두번째현재 입력 레코드(행)를 이전에 채운 배열의 키로 사용하여 두 개의 입력 파일에 대한 테스트입니다 !b[$0]. b현재 레코드가 1로 저장되어 있으면 b이전에 첫 번째 파일에서 레코드가 발견되었음을 알 수 있습니다. 부정적인 !테스트.

테스트가 true인 경우, 즉 두 번째 파일의 현재 줄이 이전에 첫 번째 파일에서 표시되지 않은 경우 기본 작업이 수행됩니다. 해당 블록이 없는 테스트의 기본 동작은 {...}현재 줄을 출력하는 것입니다(즉, 코드가 인 것처럼 동작합니다 !b[$0] { print }).


awk스크립트는 첫 번째 파일의 모든 (고유) 행을 메모리로 읽어 들이므로 다음을 실행합니다.매우대용량 파일.

이런 경우에는 다음과 같은 작업을 수행하는 것이 좋습니다.

comm -13 <( sort -u file1 ) <( sort -u file2 )

(이것은 프로세스 대체에 대해 알고 있는 쉘이 필요합니다) 또는 그냥

comm -13 file1 file2

파일이 이미 정렬되어 있는 경우.

이 생성되지 않습니다정밀한스크립트와 동일한 출력은 awk두 번 이상 발생하는 모든 행을 file2각 발생에 대해 한 번씩 출력하지만 입력에서 위 명령을 사용하는 경우에는 출력되지 않습니다 comm.sort -u

자세한 내용은 comm시스템 설명서를 참조하십시오.


댓글의 문제를 해결하려면 다음 단계를 따르세요.

  1. 예, FNR현재 입력 파일에서 읽은 레코드 수입니다.
  2. NR그리고 FNR어느 하나의 파일에 "속하지" 마십시오. 이는 단지 카운터일 뿐입니다. FNR파일 끝에 도달하면 카운터가 재설정됩니다.
  3. 파일에서 한 줄을 읽을 때 NR증가합니다 . FNRnext명령은 스크립트의 시작 부분으로 강제로 이동하여 다음 줄을 읽게 합니다. 새 줄을 읽으면 NR합계가 증가합니다.FNR
  4. 그렇다면 NR != FNR이는 첫 번째 파일 이상으로 이동했다는 의미입니다. FNR이전 파일의 끝에 도달하면 0으로 재설정되지만 NR계속 계산됩니다.
  5. $0현재 행을 보유하는 변수입니다. 파일에서 읽은 전체 줄을 저장합니다. 개최 대기 $1$2필드현재 행의 값은 IFS변수 값(일반적으로 공백)으로 분할됩니다. 현재 행이 인 경우 hello world해당 $0값을 가지며 해당 값을 가지며 hello world해당 값을 갖습니다 ( 행이 공백으로 분할되기 때문입니다). 스크립트는 "현재 입력 줄의 내용" 으로 생각할 수 있는 while을 사용합니다.$1hello$2world$0$0
  6. b[$0] = 1배열의 특정 위치/인덱스에 값을 할당하는 것입니다 b. 위치는 현재 행에 의해 결정되며 $0값 1이 할당됩니다. 이렇게 하면 배열이 b"조회 테이블"처럼 작동합니다. b[i]특정 인덱스가 1 이면 i첫 번째 입력 파일에서 발생한다는 의미입니다.
  7. !b[$0]$0인덱스에 저장된 값이 b0(또는 초기화되지 않은 경우)이면 참입니다. 즉, b[$0]값 1이 할당되지 않은 경우, 즉 두 번째 파일에서 방금 읽은 줄이 이전에 첫 번째 파일에 표시되지 않은 경우입니다. 이 테스트에 해당하는 동작(블록 없음)이 없으므로 {...}기본 동작인 인쇄를 수행합니다. $0이는 첫 번째 파일에 없는 두 번째 파일의 모든 줄을 인쇄하는 효과가 있습니다.

관련 정보