스크립트에서이 오류가 발생하는 이유는 무엇입니까? awk : script.awk : 19 :“구문 오류
2 개의 텍스트 파일이 있습니다.
1.txt
AA;00000;
BB;11111;
GG;22222;
2.txt
KK;WW;55555;11111;
KK;FF;ZZ;11111;
KK;RR;YY;11111;
이 3.txt
출력 을 생성하려고합니다 .
AA;00000;
BB;11111;KK;WW;55555;KK;FF;ZZ;KK;RR;YY;
GG;22222;
중복 필드를 제거한 후
AA;00000;
BB;11111;KK;WW;55555;FF;ZZ;RR;YY;
GG;22222;
간단히 말해서 : ;
(FS = ";") 로 구분 된 두 파일 $n
에서 파일 1 의 필드 $m
가 파일 2의 임의 위치 에있는 경우 m, n이 1이 아닌 경우에 추가 $0(file2,m)
합니다 $0(file1,n)
. 중복 필드는 피해야합니다.
해결책을 스케치 해 보겠습니다.
awk -f script.awk 2.txt 1.txt
여기서 스크립트는 다음과 같습니다.
BEGIN {
FS=";"
OFS=";"
}
NR==FNR {
allRecordsFile2[i++] = $0; next; } { for(r in allRecordsFile2) { split(allRecordsFile2[r],";",array) for(f in array) { for($2 through $n of file1 currently processed) { if $n == f --> $0 = $0";"allRecordsFile2[r]
}
}
}
## cleanup duplicates
print $0
}
나는 여전히 중복 정리를 해쳐 야하지만 아마도 이것은 중복을 추적하기 위해 계수 배열로 분할 하고 사용 $0
함으로써 수행 될 수있다 ";"
.
하지만이 스크립트를 실행 한 후 구문 오류를 반환합니다.
C:\Program Files (x86)\GnuWin32\bin>awk -f script.awk file2.txt file1.txt
awk: script.awk:17: for($2 through $n of filei currently processed)
awk: script.awk:17: “ syntax error
awk: script.awk:19: if $n == f --> $0 = $0";"allRecordsFile2[r] awk: script.awk:19: “ syntax error awk: script.awk:19: if $n == f --> $0 = $0";"allRecordsFile2[r]
awk: script.awk:19: “ syntax error
errcount:3

답변
순차 읽기를 시도하고 FNR
/를 기반으로 제어하는 대신 각 줄에서 고유 한 구성 요소를 연결 하는 출력 문자열 ( 아래) 을 읽고 분할 한 다음 빌드하는 데 NR
사용하지 않는 이유 는 무엇입니까? 다음과 유사한 작업을 수행 할 수 있습니다.getline
2.txt
';'
o
awk '{
printf "%s", $0 } /^BB/ { o = "" while (getline tmp < "2.txt") { n = split (tmp,arr,";") for (i=1; i<=n; i++) if(!match($0,arr[i]) && !match(o,arr[i]))
o=o arr[i]";"
}
printf "%s", o
}
{
print ""
}
' 1.txt
사용 / 출력 예시
1.txt
및 2.txt
( 1.txt
다시 이름을 잘못 지정 )에 예제 데이터를 입력 하면 다음을 받게됩니다.
$ awk '{ > printf "%s", $0
> }
> /^BB/ {
> o = ""
> while (getline tmp < "2.txt") {
> n = split (tmp,arr,";")
> for (i=1; i<=n; i++)
> if(!match($0,arr[i]) && !match(o,arr[i]))
> o=o arr[i]";"
> }
> printf "%s", o
> }
> {
> print ""
> }
> ' 1.txt
AA;00000;
BB;11111;KK;WW;55555;FF;ZZ;RR;YY;
GG;22222;
당신이 원하는 것 같습니다.
두 개의 파일 이름을 인수로 사용하는 스크립트
Windows는 ARGV
. awk
스크립트 내에서 실행할 때 규칙을 작은 따옴표로 묶지 마십시오 . 예 :
#!/usr/bin/awk -f
NR != FNR {
exit
}
{
printf "%s", $0
}
/^BB/ {
o = ""
while (getline tmp < ARGV[2]) {
n = split (tmp,arr,";")
for (i=1; i<=n; i++)
if(!match($0,arr[i]) && !match(o,arr[i]))
o=o arr[i]";"
}
printf "%s", o
}
{
print ""
}
( 참고 :/usr/bin/awk
통역사를 가지고 있는 것으로 변경해야합니다 )
사용법은 다음과 같습니다. ./test.awk 1.txt 2.txt
도움이되는지 알려주세요.
연관 배열의 키를 사용하면 중복 항목을 처리하는 데 편리합니다. 다차원 배열을 위해 GNU awk가 필요합니다.
BEGIN { FS = OFS = ";" }
NR == FNR {
for (i=1; i<NF-1; i++)
f2[$(NF-1)][$i] = ++n
next
}
FNR == 1 {
# this joins all the 2nd-level indices
# the order of them is undefined.
for (x in f2) {
s = ""
for (y in f2[x])
s = s y OFS
a[x] = s
}
}
$(NF - 1) in a { $NF = a[$(NF-1)] }
1
그때
gawk -f script.awk {2,1}.txt
생산하다
AA;00000;
BB;11111;55555;WW;KK;RR;YY;FF;ZZ;
GG;22222;
URL에서 "작동하지 않는다"는 증거가 더 필요합니다.
$ cat 1.txt
AA;http://a.o/f/i.p?t=00000;
BB;http://a.o/f/i.p?t=11111;
GG;http://a.o/f/i.p?t=22222;
$ cat 2.txt KK;WW;55555;http://a.o/f/i.p?t=11111; KK;FF;ZZ;http://a.o/f/i.p?t=11111; KK;RR;YY;http://a.o/f/i.p?t=11111; $ gawk -f script.awk {2,1}.txt
AA;http://a.o/f/i.p?t=00000;
BB;http://a.o/f/i.p?t=11111;55555;WW;KK;RR;YY;FF;ZZ;
GG;http://a.o/f/i.p?t=22222;