Remplacer une colonne dans un fichier tout en conservant le format d’espace

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 

Exemple

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 

Explication

Va append plus tard