안녕하세요 여러분, 몇 주 전에 저는 사용자에게 텍스트 파일 이름을 묻고 단어를 묻는 C 프로그램을 작성했습니다. 그런 다음 프로그램은 텍스트 왼쪽에 숫자가 있는 입력 텍스트 파일을 출력하고 해당 단어가 텍스트 파일에 나타나는 횟수를 출력합니다. 또한 해당 단어가 나타나는 일치하는 줄 번호를 출력합니다.
실제적인 예는 다음과 같습니다.
텍스트 파일 이름을 입력하세요: bond.txt
Enter the pattern to search for: Bond File contents: 1) Secret agent Bond had been warned not to tangle with Goldfinger. 2) But the super-criminal's latest obsession was too strong, too dangerous. 3) He had to be stopped. 4) Goldfinger was determined to take possession of half the supply of 5) mined gold in the world--to rob Fort Knox! 6) For this incredible venture he had enlisted the aid of the top 7) criminals in the U.S.A, including a bevy of beautiful thieves from the 8) Bronx. And it would take all of Bond's unique talents to make it fail-- 9) as fail it must. There is a match on line 1 There is a match on line 8 'Bond' appeared 2 times in the file bond.txt.
현재 저는 C로 작성한 프로그램을 반복하되 awk를 사용하여 awk 프로그래밍을 연습하려고 합니다.
제가 지금까지 수집한 내용은 다음과 같습니다.
BEGIN{
printf("Enter filename : ")
getline file < "-"
while((getline < file)) {
{print "File Contents:"}
{printf("%5d) %s\n", NR,$0)}
}
}
사용자가 입력한 단어를 검색하기 위해 텍스트 파일을 한 줄씩 구문 분석할 수 있는 가장 좋고 효율적인 방법은 무엇입니까? 어떤 팁이나 요령이 있나요? 감사해요.
답변1
$ awk '/Bond/{c++; print "There is a match on line " NR} END{print "\"Bond\" appeared " c " times in the file " FILENAME}' bond.txt
There is a match on line 1
There is a match on line 8
"Bond" appeared 2 times in the file bond.txt
어떻게 작동하나요?
awk는 모든 입력 라인을 암시적으로 반복합니다.
/Bond/{c++; print "There is a match on line " NR}
regex 와 일치하는 줄의 경우
Bond
카운터가c
증가하고 일치가 발생한 줄을 보여주는 메시지가 인쇄됩니다. awk에서 지금까지 읽은 줄 수는 입니다NR
.END{print "\"Bond\" appeared " c " times in the file " FILENAME}
마지막 줄을 읽은 후 총 일치 항목 수를 보여주는 메시지가 인쇄됩니다.
여러 줄 버전
코드를 여러 줄에 걸쳐 분산시키려는 경우:
awk '
/Bond/{
c++
print "There is a match on line " NR
}
END{
print "\"Bond\" appeared " c " times in the file " FILENAME
}
' bond.txt
파일 요약 전에 파일 내용 표시
이 방법은 파일을 두 번 읽습니다. 처음에는 줄 번호로 형식이 지정된 파일 버전을 인쇄합니다. 두 번째 인쇄 요약 출력:
$ awk 'FNR==NR{printf("%5d) %s\n", NR,$0);next} /Bond/{c++; print "There is a match on line " FNR} END{print "\"Bond\" appeared " c " times in the file " FILENAME}' bond.txt{,}
1) Secret agent Bond had been warned not to tangle with Goldfinger.
2) But the super-criminal's latest obsession was too strong, too dangerous.
3) He had to be stopped.
4) Goldfinger was determined to take possession of half the supply of
5) mined gold in the world--to rob Fort Knox!
6) For this incredible venture he had enlisted the aid of the top
7) criminals in the U.S.A, including a bevy of beautiful thieves from the
8) Bronx. And it would take all of Bond's unique talents to make it fail--
9) as fail it must.
There is a match on line 1
There is a match on line 8
"Bond" appeared 2 times in the file bond.txt
위 버전과 첫 번째 버전에는 두 가지 차이점이 있습니다. 먼저 bond.txt bond.txt
bash를 사용하여 명령줄에 파일을 두 번 제공하거나버팀대 확장.bond.txt{,}
둘째, 다음 명령을 추가했습니다.
FNR==NR{printf("%5d) %s\n", NR,$0);next}
FNR==NR
이 명령은 NR이 지금까지 읽은 총 라인 수이고 FNR이 현재 파일에서 읽은 라인 수인 경우에만 실행됩니다. 그래서 그 당시 FNR==NR
우리는 처음으로 파일을 읽고 있었습니다. 그런 다음 printf
출력 형식을 지정하고 next
스크립트의 나머지 명령을 건너뛰고 해당 줄로 이동합니다.
선택하다
이 버전에서는 파일을 한 번만 읽고, 형식화된 버전을 인쇄하고, 마지막에 인쇄할 요약 정보를 저장합니다.
$ awk '{printf("%5d) %s\n", NR,$0)} /Bond/{c++; s=s ORS "There is a match on line " FNR} END{print s; print "\"Bond\" appeared " c " times in the file " FILENAME}' bond.txt
1) Secret agent Bond had been warned not to tangle with Goldfinger.
2) But the super-criminal's latest obsession was too strong, too dangerous.
3) He had to be stopped.
4) Goldfinger was determined to take possession of half the supply of
5) mined gold in the world--to rob Fort Knox!
6) For this incredible venture he had enlisted the aid of the top
7) criminals in the U.S.A, including a bevy of beautiful thieves from the
8) Bronx. And it would take all of Bond's unique talents to make it fail--
9) as fail it must.
There is a match on line 1
There is a match on line 8
"Bond" appeared 2 times in the file bond.txt
답변2
다음은 예제 C 코드의 기능을 복제해야 합니다.
#!/bin/awk -f
BEGIN{
printf("Enter the name of a text file: ")
getline file < "-"
printf("Enter the pattern to search for: ")
getline searchfor < "-"
print "File contents:"
while (getline < file){
# NR does not work for files read with getline in this way, so....
linenum++
printf("%5d) %s\n",linenum,$0)
if ($0 ~ searchfor){
matchcount++
matches=matches sprintf("There is a match on line %d\n",linenum)
}
}
print matches
printf("'%s' appeared %d times in file %s.\n",searchfor,matchcount,file)
}