J’ai un code ci-dessous qui remplace la 4ème colonne de fileA en fonction des données dans le fichierB mais la sortie n’a pas conservé les espaces du fichier d’origine. Y a-t-il un moyen de le faire?
tr , " " <fileB | awk 'NR==FNR{a[$2]=$1;next} {$4=a[$4];print}' - fileA
déposer un
xxx xxx xxx Z0002
fileB
3100,3000 W0002,Z0002
sortie en utilisant le code ci-dessus:
xxx xxx xxx W0002
production attendue:
xxx xxx xxx W0002
Cela devrait faire:
awk 'FNR==NR {split($0,a,",");b[a[2]]=a[1];next} {n=split($0,d,/[^[:space:]]*/);if(b[$4])$4=b[$4];for(i=1;i<=n;i++) printf("%s%s",d[i],$i);print ""}' fileB fileA
Il stocke les espaces dans un tableau pour pouvoir le réutiliser ultérieurement
Exemple:
cat fileA xxx xxx xxx Z0002 not change this xxx xxx Z0002 zzz xxx Z000223213 xxx Z0002 xxx xxx xxx Z0002
cat fileB 3100,3000 W0002,Z0002
awk 'FNR==NR {split($0,a,",");b[a[2]]=a[1];next} {n=split($0,d,/[^[:space:]]*/);if(b[$4])$4=b[$4];for(i=1;i<=n;i++) printf("%s%s",d[i],$i);print ""}' fileB fileA xxx xxx xxx W0002 not change this xxx xxx Z0002 zzz xxx Z000223213 xxx W0002 xxx xxx xxx Z0002
Certains plus lisibles et comment cela fonctionne:
awk ' FNR==NR { # For the first file "fileB" split($0,a,",") # Split it to an array "a" using "," as separator b[a[2]]=a[1] # Store the data in array "b" using second column as index next # Skip to next record } { # Then for the file "fileA" n=split($0,d,/[^[:space:]]*/) # Split the spaces inn group and store them in array "d" if(b[$4]) # If array "b" as data for field "4" $4=b[$4] # Change filed "4" to data found in array "b" for(i=1;i<=n;i++) # Loop trough all field in the line printf("%s%s",d[i],$i) # print correct separator and data print "" # Add new line at the end } ' fileB fileA # Read the files.
Utilisez gsub (substitution des expressions régulières), avec un motif d’espace blanc avant et la fin de la ligne $
après la résolution du problème.
Fichier de test:
$ cat fileA xxx xxx xxx Z0002 xxx xxx Z0002 xxx xxx xxx xxx Z0002YY
Commande exécutée et résultats:
$ tr , " "
Réponse longue
C’est un peu exagéré pour cette question mais je pense que ce sera utile pour les autres.
Cela évitera les problèmes avec les métacaractères et le motif se produisant ailleurs sur la ligne.
awk 'FNR==NR {split($0,a,",");b[a[2]]=a[1];next} { while(match(substr($0,x+=(RSTART+RLENGTH-(x>1?1:0))),"[^[:space:]]+")){ E[++D]=(RSTART+x-(x>1?1:0)) F[D]=E[D]+RLENGTH } } b[$4]~/./{$0=substr($0,0,E[4]-1) b[$4] substr($0,F[4])} {x=1;D=0;delete E}1' FILEB FILEA
consortingbution
DÉPOSER UN
xxx Z0002 xxx Z0002 xxx xxx xxx Z0002 xxx Z0002 xxx dsasa xxx xxx xxx Z0002
FILEB
3100,3000 W0002,Z0002
Sortie
xxx Z0002 xxx W0002 xxx xxx xxx Z0002 xxx Z0002 xxx dsasa xxx xxx xxx Z0002
Va append plus tard