Pourquoi est-ce que j'obtiens cette erreur dans mon script? awk: script.awk: 19: "erreur de syntaxe
J'ai 2 fichiers texte
1.txt
AA;00000;
BB;11111;
GG;22222;
2.txt
KK;WW;55555;11111;
KK;FF;ZZ;11111;
KK;RR;YY;11111;
J'essaye de générer cette 3.txt
sortie:
AA;00000;
BB;11111;KK;WW;55555;KK;FF;ZZ;KK;RR;YY;
GG;22222;
et après avoir supprimé les champs en double, je devrais avoir ceci
AA;00000;
BB;11111;KK;WW;55555;FF;ZZ;RR;YY;
GG;22222;
En termes simples: dans deux fichiers séparés par ;
(FS = ";"), si un champ $n
du fichier 1 est présent à un emplacement quelconque $m
du fichier 2, où m, n ne vaut pas 1, alors ajoutez-le $0(file2,m)
à $0(file1,n)
. Les champs en double doivent être évités.
J'essaierai d'esquisser une solution
awk -f script.awk 2.txt 1.txt
où script est le suivant:
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
}
Je dois encore marteler les doublons de nettoyage, mais probablement cela peut être fait en se divisant $0
par ";"
et en utilisant un tableau de comptage pour garder la trace des doublons.
Mais après avoir exécuté ce script, je renvoie des erreurs de syntaxe
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

Réponses
Plutôt que d'essayer des lectures séquentielles et un contrôle basé sur FNR
/ NR
, pourquoi ne pas utiliser getline
pour lire 2.txt
et fractionner ';'
, puis créer la chaîne de sortie ( o
ci-dessous) concaténant les composants uniques de chaque ligne? Vous pouvez faire quelque chose de similaire à:
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
Exemple d'utilisation / sortie
Avec vos données d'exemple dans 1.txt
et 2.txt
(que vous avez à 1.txt
nouveau mal nommées ), vous recevrez:
$ 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;
Ce qui ressemble à ce que vous voulez.
En tant que script prenant deux noms de fichiers comme arguments
Windows doit suivre les mêmes conventions en utilisant ARGV
. Notez que vous n'incluez pas les guillemets simples autour des règles lors de l'exécution dans un awk
script, par exemple
#!/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 ""
}
( note: vous devrez changer l' /usr/bin/awk
interprète pour celui que vous avez)
L'utilisation serait, par exemple ./test.awk 1.txt 2.txt
Faites-moi savoir si cela vous a été utile.
L'utilisation des clés d'un tableau associatif est pratique pour gérer les éléments en double. Cela nécessite GNU awk pour le tableau multidimensionnel
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
ensuite
gawk -f script.awk {2,1}.txt
produit
AA;00000;
BB;11111;55555;WW;KK;RR;YY;FF;ZZ;
GG;22222;
J'aurai besoin de plus de preuves indiquant que cela "ne fonctionne pas" avec les 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;