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