4 votes

Comment remplacer des lignes d'un fichier texte par des lignes d'un autre fichier sur la base de champs clés correspondants ?

input.txt

1,Ram,Fail
2,John,Fail
3,Ron,Success

param.txt (Nouvelle entrée)

1,Sam,Success
2,John,Sucess

Maintenant je veux remplacer toute la ligne dans input.txt par celle présente dans param.txt. La première colonne agira comme une clé primaire.

Sortie.txt

1,Sam,Success
2,John,Sucess
3,Ron,Success

J'ai essayé de

awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' input.txt param.txt > Output.txt 

Mais il fusionne le contenu des fichiers.

4voto

potong Points 18653

Cela peut fonctionner pour vous (GNU sed) :

 sed 's|^\([^,]*,\).*|/^\1/c\\&|' param.txt | sed -f - input.txt

Explication :

  • Convertir param.txt en un sed script utilisant le premier champ comme adresse pour modifier la ligne dans le fichier input.txt . s|^\([^,]*,\).*|/^\1/c\\&|
  • Exécutez le script contre le fichier input.txt . sed -f - input.txt

4voto

chepner Points 54078

Cela peut se faire en appelant la commande sort :

sort -t, -k1,1n -us param.txt input.txt

Utilisez un tri numérique stable sur le premier champ délimité par des virgules, et dressez une liste param.txt avant input.txt afin que les lignes correctes, plus récentes, soient privilégiées lors de l'élimination des doublons.

2voto

Alan Points 494

Vous pouvez utiliser join(1) pour que cela fonctionne :

$ join -t, -a1 -j1 Input.txt param.txt | sed -E 's/,.*?,.*?(,.*?,.*?)/\1/'
1,Sam,Success
2,John,Sucess
3,Ron,Success

sed as a pipe tail dépouille les champs de Input.txt des lignes remplacées.

Cela ne fonctionnera que si les deux fichiers d'entrée sont triés par le premier champ.

2voto

CodeGnome Points 25402

L'awk pur n'est pas vraiment l'outil adéquat pour ce travail. Si vous doit n'utiliser que awk, https://stackoverflow.com/a/5467806/1301972 est un bon point de départ pour vos efforts.

Cependant, Unix fournit quelques outils qui vous aideront à fournir à awk les données d'entrée appropriées à ce que vous essayez de faire.

$ join -a1 -t, <(sort -n input.txt) <(sort -n param.txt) |
     awk -F, 'NF > 3 {print $1 "," $4 "," $5; next}; {print}'

En fait, vous fournissez à awk un fichier unique contenant les lignes reliées aux clés du fichier input.txt. Ensuite, awk peut analyser les champs que vous souhaitez afficher ou rediriger vers votre fichier de sortie.

2voto

jaypal Points 34440

Cela devrait fonctionner en awk

awk -F"," 'NR==FNR{a[$1]=$0;next} ($1 in a){ print a[$1]; next}1' param.txt input.txt

Test :

$ cat input.txt 
1,Ram,Fail
2,John,Fail
3,Ron,Success
$ cat param.txt 
1,Sam,Success
2,John,Sucess
$ awk -F"," 'NR==FNR{a[$1]=$0;next} ($1 in a){ print a[$1]; next}1' param.txt input.txt 
1,Sam,Success
2,John,Sucess
3,Ron,Success

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X