Réponses:
La réponse ci-dessous est basée sur un Q & A similaire dans SO avec quelques modifications pertinentes:
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($2 in dict) ? dict[$2] : $2}1' file2.txt file1.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
L'idée est de créer une carte de hachage avec index et de l'utiliser comme dictionnaire.
Pour la 2e question que vous avez posée dans votre commentaire ( que faut-il changer si la deuxième colonne de file1.txt
sera la sixième colonne ):
Si le fichier d'entrée sera comme file1b.txt
:
item1 A5 B C D carA
item2 A4 1 2 3 carB
item3 A3 2 3 4 carC
item4 A2 4 5 6 platD
item5 A1 7 8 9 carE
La commande suivante le fera:
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($6 in dict) ? dict[$6] : $6;$3="";$4="";$5="";$6=""}1' file2.txt file1b.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
Je sais que tu as dit awk
, mais il y a une join
commande à cet effet ...
{
join -o 1.1,2.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
join -v 1 -o 1.1,1.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
} | sort -k 1
Ce serait suffisant avec la première join
commande s'il n'y avait pas cette ligne:
item4 platD
La commande dit essentiellement: jointure basée sur la deuxième colonne du premier fichier ( -1 2
) et la première colonne du deuxième fichier ( -2 1
), et affiche la première colonne du premier fichier et la deuxième colonne du deuxième fichier ( -o 1.1,2.2
). Cela ne montre que les lignes appariées. La deuxième commande join indique presque la même chose, mais elle indique d'afficher les lignes du premier fichier qui n'ont pas pu être jumelées ( -v 1
), et de sortir la première colonne du premier fichier et la deuxième colonne du premier fichier ( -o 1.1,1.2
). Ensuite, nous trions la sortie des deux combinés. sort -k 1
signifie trier en fonction de la première colonne et sort -k 2
signifie trier en fonction de la seconde. Il est important de trier les fichiers en fonction de la colonne de jointure avant de les transmettre join
.
Maintenant, j'ai écrit le tri deux fois, parce que je n'aime pas joncher mes répertoires de fichiers si je peux l'aider. Cependant, comme l'a dit David Foerster, selon la taille des fichiers, vous souhaiterez peut-être trier les fichiers et les enregistrer d'abord pour ne pas avoir à attendre de les trier deux fois. Pour donner une idée des tailles, voici le temps qu'il faut pour trier 1 million et 10 millions de lignes sur mon ordinateur:
$ ruby -e '(1..1000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 1million.txt
$ ruby -e '(1..10000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 10million.txt
$ head 10million.txt
item530284 plat530284
item7946579 plat7946579
item1521735 plat1521735
item9762844 plat9762844
item2289811 plat2289811
item6878181 plat6878181
item7957075 plat7957075
item2527811 plat2527811
item5940907 plat5940907
item3289494 plat3289494
$ TIMEFORMAT=%E
$ time sort 1million.txt >/dev/null
1.547
$ time sort 10million.txt >/dev/null
19.187
Cela représente 1,5 seconde pour 1 million de lignes et 19 secondes pour 10 millions de lignes.
%E
format horaire) est moins intéressant pour mesurer les performances de calcul. Le temps CPU en mode utilisateur ( %U
ou simplement une TIMEFORMAT
variable non définie ) serait beaucoup plus significatif.
%U
.