Warum erhalte ich diesen Fehler in meinem Skript? awk: script.awk: 19: “Syntaxfehler
Ich habe 2 Textdateien
1.txt
AA;00000;
BB;11111;
GG;22222;
2.txt
KK;WW;55555;11111;
KK;FF;ZZ;11111;
KK;RR;YY;11111;
Ich versuche diese 3.txt
Ausgabe zu generieren :
AA;00000;
BB;11111;KK;WW;55555;KK;FF;ZZ;KK;RR;YY;
GG;22222;
und nachdem ich doppelte Felder entfernt habe, sollte ich dies haben
AA;00000;
BB;11111;KK;WW;55555;FF;ZZ;RR;YY;
GG;22222;
In einfach Worten: in zwei Dateien , die getrennt sind durch ;
(FS = „;“), wenn ein Feld $n
von Datei 1 , die in einem beliebigen Ort $m
in der Datei 2, wobei m, n nicht 1 ist , dann append $0(file2,m)
zu $0(file1,n)
. Doppelte Felder müssen vermieden werden.
Ich werde versuchen, eine Lösung zu skizzieren
awk -f script.awk 2.txt 1.txt
Dabei ist das Skript wie folgt:
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
}
Ich brauche immer noch die Bereinigung um Duplikate zu hämmern, aber wahrscheinlich kann dies durch Spaltung erfolgen $0
durch ";"
und eine Zählung Array Spur von Duplikaten zu halten.
Aber nachdem ich dieses Skript ausgeführt habe, gebe ich Syntaxfehler zurück
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

Antworten
Anstatt sequenziell versuchen liest und Steuern basierend auf FNR
/ NR
, warum nicht verwenden , getline
liest aus 2.txt
und Split auf ';'
und dann die Ausgabezeichenfolge bauen ( o
unten) aus jeder Zeile einzigartige Komponenten verketten? Sie könnten etwas Ähnliches tun wie:
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
Beispiel Verwendung / Ausgabe
Mit Ihren Beispieldaten in 1.txt
und 2.txt
(die Sie 1.txt
erneut falsch benannt haben ) erhalten Sie:
$ 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;
Welches sieht aus wie was Sie wollen.
Als Skript, das zwei Dateinamen als Argumente verwendet
Windows sollte die gleichen Konventionen wie verwenden ARGV
. Beachten Sie, dass Sie die einfachen Anführungszeichen nicht in die Regeln aufnehmen, wenn Sie in einem awk
Skript ausgeführt werden, z
#!/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 ""
}
( Hinweis: Sie müssen den /usr/bin/awk
Interpreter auf das ändern , was Sie haben.)
Verwendung wäre zB ./test.awk 1.txt 2.txt
Lassen Sie mich wissen, ob das hilft.
Die Verwendung der Schlüssel eines assoziativen Arrays ist praktisch, um doppelte Elemente zu verarbeiten. Dies erfordert GNU awk für das mehrdimensionale Array
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
dann
gawk -f script.awk {2,1}.txt
produziert
AA;00000;
BB;11111;55555;WW;KK;RR;YY;FF;ZZ;
GG;22222;
Ich brauche mehr Beweise dafür, dass es mit URLs "nicht funktioniert":
$ 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;