NR 및 FNR은 무엇이며 "NR == FNR"은 무엇을 의미합니까?


85

.NET을 사용하여 파일 비교를 배우고 있습니다 awk.

아래와 같은 구문을 찾았습니다.

awk 'NR==FNR{a[$1];next}$1 in a{print $1}' file1 file2

NR==FNR이것 의 의미가 무엇인지 이해할 수 없었 습니까? 내가 시도 FNR==NR하면 동일한 출력을 얻습니까?

정확히 무엇을합니까?


20
당신이 경우에 놀랄 것 a==bb==a같은 결과를 생산?
Ed Morton

답변:


93

awk FNR에서 현재 파일의 레코드 번호 (일반적으로 줄 번호)를 NR참조하고 총 레코드 번호를 나타냅니다. 연산자 ==는 두 개의 주변 피연산자가 같을 때 true를 반환하는 비교 연산자입니다.

NR==FNR, FNR각 파일의 첫 번째 줄에 대해 다시 1 로 재설정되지만 NR계속 증가 하므로 첫 번째 파일에 대해서만 조건 이 참 임을 의미합니다 .

이 패턴은 일반적으로 첫 번째 파일에서만 작업을 수행하는 데 사용됩니다. next가 첫 번째 이외의 파일에서 실행되도록 더 명령을 건너 뜁니다 블록 수단 내부.

조건 FNR==NR은 동일한 두 피연산자를와 비교 NR==FNR하므로 동일한 방식으로 작동합니다.


3
"="는 때때로 동등성을 테스트하는 데 사용되며 때로는 할당을 수행하는 데 사용됩니다. FNR == NR은 할당에 이중 등호가 사용 된 경우 NR == FNR과 다릅니다. 따라서이 질문자와 같이 awk에 익숙하지 않은 사람에게는 동일한 지 묻는 것이 합리적입니다.
Todd Walton

@ToddWalton 좋은 지적! 또 다른 예 : a='3x'; if [[ $a == 3* ]]; then echo yes; fi당신은 양쪽을 전환 할 수 없습니다 ==.
Walter A

@WalterA 그렇습니다 (적어도 Bash에서는). 내 대답에 개선을 제안하고 있습니까?
Tom Fenech

1
아니, 당신의 대답은 괜찮습니다. 커뮤니티가 우리 답변을 좋아하는 것을 정말보고 싶습니다. 우리는 다른 스타일을 사용하며 둘 다 매우 도움이되는 것으로 간주됩니다. 방금 당신에게 찬성표를주었습니다. 그래서 이번에는 같은 수의 찬성표가 있습니다.
Walter A

72

file1에도있는 file2에서 키 (행의 첫 번째 단어)를 찾습니다.
1 단계 : 배열 a를 파일 1의 첫 단어로 채 웁니다.

awk '{a[$1];}' file1

2 단계 : 동일한 명령에서 배열 a를 채우고 파일 2를 무시합니다. 이를 위해 현재 입력 파일의 번호로 지금까지 총 레코드 수를 확인하십시오.

awk 'NR==FNR{a[$1]}' file1 file2

3 단계 : }파일 1을 구문 분석 할 때 발생할 수있는 작업 무시

awk 'NR==FNR{a[$1];next}' file1 file2 

4 단계 : 배열 a에서 발견되면 file2의 키 인쇄

awk 'NR==FNR{a[$1];next} $1 in a{print $1}' file1 file2

4
이 원 라이너의 멋진 게시 중단. 1 단계의 세미콜론이 필요합니까?
Tomasz Gandor

2
@TomaszGandor 세미콜론은 1 단계에서 필요하지 않습니다. 3 단계에서 추가 할 수도 있었지만 ;next이상한 추가입니다 ( next3 단계에서 세미콜론 을 추가 하고 필요함). 를 사용하여 1 단계를 테스트 할 수 있습니다 awk '{a[$1]} END { for (k in a) { print "a[k]=" k } }' file1.
Walter A

45

조회 NRFNRAWK 설명서에서 다음 조건이 무엇인지 스스로에게 물어 어떤에서 NR==FNR다음 예제 :

$ cat file1
a
b
c

$ cat file2
d
e

$ awk '{print FILENAME, NR, FNR, $0}' file1 file2
file1 1 1 a
file1 2 2 b
file1 3 3 c
file2 4 1 d
file2 5 2 e

처리중인 파일 번호를 인쇄 할 수도 있습니까? 그것에 대한 내장 변수가 있습니까? (저는 그것에 대한 변수를 생성하고 NR이 1 일 때마다 증가시킬 수 있다는 것을 압니다)
LEo

GNU awk에서 그 변수는입니다 ARGIND. 그렇지 않으면 할 수 있습니다 FNR==1{ print ++file_nr }.
Ed Morton

나는 할 수있다하면, 또 다른 질문으로 질문에 대답하면 해당 효율적이지 않다)
플로리안 Castelain

나는 질문하지 않고 OPs 질문에 대한 답변을 얻는 방법을 보여주었습니다.
Ed Morton

20

가 있습니다 awk내장 변수.

NR -처리 된 총 레코드 수를 제공합니다.

FNR -각 입력 파일에 대한 총 레코드 수를 제공합니다.


15

파일 a.txt 및 b.txt가 있다고 가정합니다.

cat a.txt
a
b
c
d
1
3
5
cat b.txt
a
1
2
6
7

NR 및 FNR은 awk 기본 제공 변수입니다. NR-처리 된 총 레코드 수를 제공합니다. (이 경우 a.txt 및 b.txt 모두) FNR-각 입력 파일에 대한 총 레코드 수를 제공합니다 (a.txt 또는 b.txt의 레코드).

awk 'NR==FNR{a[$0];}{if($0 in a)print FILENAME " " NR " " FNR " " $0}' a.txt b.txt
a.txt 1 1 a
a.txt 2 2 b
a.txt 3 3 c
a.txt 4 4 d
a.txt 5 5 1
a.txt 6 6 3
a.txt 7 7 5
b.txt 8 1 a
b.txt 9 2 1

NR == FNR과 일치하는 첫 번째 항목을 건너 뛰려면 "next"추가

b.txt 및 a.txt

awk 'NR==FNR{a[$0];next}{if($0 in a)print FILENAME " " NR " " FNR " " $0}' a.txt b.txt
b.txt 8 1 a
b.txt 9 2 1

b.txt에는 있지만 a.txt에는 없습니다.

 awk 'NR==FNR{a[$0];next}{if(!($0 in a))print FILENAME " " NR " " FNR " " $0}' a.txt b.txt
b.txt 10 3 2
b.txt 11 4 6
b.txt 12 5 7

awk 'NR==FNR{a[$0];next}!($0 in a)' a.txt b.txt
2
6
7
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.