basefile.txt
많은 줄의 이름을 딴 파일이 있습니다. 파일의 레코드는 컬렉션에 따라 논리적으로 그룹화됩니다.
예를 들어:
"GRP_START","LINE1"........
"A"
"B--BOOM"
"C"
"GRP_START","LINE1"........
"A"
"B--DOOM"
"C"
"D"
"E"
"F"
"G"
"GRP_START","LINE1"........
"E"
"F"
"G"
"C--MOOM"
"GRP_START","LINE1"........
내가 원하는 것은 이러한 검색 문자열을 keywords.txt
다음 데이터가 포함된 별도의 파일에 넣는 것입니다.
BOOM
DOOM
MOOM
파일에서 텍스트를 하나씩 읽고 keywords.txt
해당 텍스트를 검색하여 basefile.txt
특정 레코드를 쓰는 명령이 필요합니다.finalfile.txt
구체적인 기록은 다음과 같습니다. 텍스트가 있는 컬렉션을 검색해야 합니다.
예: 위 파일에서.
이 명령은 BOOM을 검색하고 다음 줄을 반환해야 합니다.
"GRP_START","LINE1"........
"A"
"B--BOOM"
"C"
이 명령은 DOOM을 검색하고 다음 줄을 반환해야 합니다.
"GRP_START","LINE1"........
"A"
"B--DOOM"
"C"
"D"
"E"
"F"
"G"
그래서 GRP_START는 그룹의 시작부터 다음 GRP_START까지 기록이 기록되기를 원합니다 finalfile.txt
.
답변1
다음 awk
스크립트는 데이터 파일을 읽고 각 레코드를 lines
변수에 임시로 저장합니다. word
변수의 키워드가 레코드에서 발견 되면 do_output
변수는 1(true)로 설정됩니다. 키워드가 발견되고 다음 레코드나 파일 끝에 도달하면 키워드 레코드가 출력됩니다.
#!/usr/bin/awk -f
/^"GRP_START"/ {
if (do_output) {
exit;
}
lines = $0;
next;
}
$0 ~ word {
do_output = 1;
}
{
lines = sprintf("%s\n%s", lines, $0);
}
END {
if (do_output) {
print lines;
}
}
테스트해보세요:
$ awk -v word="MOOM" -f script.awk basefile.txt
"GRP_START","LINE1"........
"E"
"F"
"G"
"C--MOOM"
그런 다음 필수 키워드를 반복하면 됩니다.
#!/bin/sh
while read -r word; do
awk -v word="$word" -f script.awk basefile.txt
done <keywords.txt >finalfile.txt
향후 개선을 위한 제안: 먼저 키워드를 배열로 읽은 다음 basefile.txt
데이터 파일을 한 번만 구문 분석합니다.
답변2
노력하다:
awk 'FNR==NR{re=re (re?"|":"")$0;next} /^"GRP_START"/{if (rec~re)print rec; rec=$0;next} {rec=rec"\n"$0} END{if (rec~re)print rec}' keywords.txt basefile.txt
예:
$ awk 'FNR==NR{re=re (re?"|":"")$0;next} /^"GRP_START"/{if (rec~re)print rec; rec=$0;next} {rec=rec"\n"$0} END{if (rec~re)print rec}' keywords.txt basefile.txt
"GRP_START","LINE1"........
"A"
"B--BOOM"
"C"
"GRP_START","LINE1"........
"A"
"B--DOOM"
"C"
"D"
"E"
"F"
"G"
"GRP_START","LINE1"........
"E"
"F"
"G"
"C--MOOM"
어떻게 작동하나요?
FNR==NR{re=re (re?"|":"")$0;next}
첫 번째 파일을 읽는 동안
keywords.txt
모든 단어와 일치하는 정규식을 구성합니다. 예를 들어 샘플 데이터의 경우re
값이BOOM|DOOM|MOOM
./^"GRP_START"/{if (rec~re)print rec; rec=$0;next}
새 레코드의 시작 부분에 도달할 때마다 에 저장된 마지막 레코드가 에
rec
저장된 정규식과 일치 하는지 확인합니다re
. 그렇다면 인쇄해 보겠습니다. 다음으로rec
현재 줄로 재설정하려면 나머지 명령을 건너뛰고 해당next
줄로 이동합니다.rec=rec"\n"$0
다른 모든 행의 경우 이를 에 추가합니다
rec
.END{if (rec~re)print rec}
파일을 읽은 후 최종 레코드가 정규식과 일치하는지 확인
re
하고 일치하면 인쇄합니다.