Rejoindre un champ d’index avec un trait d’union dans Unix

Je suis nouveau sur Unix et j’ai du mal à joindre deux fichiers texte délimités par des tabulations basés sur un champ qui a un index avec un trait d’union. Par exemple:

file1.txt 33-47 10 22 -99 10 33-48 15 22 165 456 33-101 10 22 -99 15.8 33-126 10 22 -99 15.5 34-133 10 22 -99 13 40-109 10 22 -99 12 41-102 88 21 -99 20 45-169 54 214 -99 4 100-11 652 524 87 5 101-25 45 54 153 8 101-26 1285 12 155 9.5 

et

 file2.txt 1 5432 545 33-101 1 5524 5420 33-126 0 855520 52220 33-47 0 5463 5420 34-133 0 5563 5423 40-109 1 6098 -99 40-109 

Essentiellement, le fichier 1 est une table de recherche et je souhaite append la ligne correspondante du fichier 1 au fichier 2 afin de créer une table complète de variables, à savoir:

 file3.txt (expected) 1 5432 545 33-101 10 22 -99 15.8 1 5524 5420 33-126 10 22 -99 15.5 0 855520 52220 33-47 10 22 -99 10 0 5463 5420 34-133 10 22 -99 13 0 5563 5423 40-109 10 22 -99 12 1 6098 -99 40-109 10 22 -99 12 

J’utilise Cygwin, et j’ai d’abord essayé de sortinger les champs numériquement, normalement, avec les parameters régionaux LC_COLLATE = C, ainsi qu’un certain nombre de commandes awk NR == FNR, mais j’ai toujours un fichier vierge.

C’est tout nouveau et très frustrant. S’il vous plait aidez si vous le pouvez!

Je vous remercie!

Cela fonctionne pour moi, mais je ne suis pas sur Cygwin:

 awk 'NR==FNR{info[$1]=gensub(/[^\t]*\t/,"",1)} NR!=FNR{printf"%s\t%s\n",$0,info[$NF]}' file1.txt file2.txt 

Je suis sûr que quelqu’un peut améliorer cela …

Je serais très intéressé de savoir comment vous avez join pour travailler.

Voici un moyen très laid:

 a='{split($f, a, /-/); $f = sprintf("%05d%05d", a[1], a[2]); print}' join -1 4 -2 1 -o 1.1 1.2 1.3 0 2.2 2.3 2.4 2.5 2.6 2.7 2.8 \ <(awk -vf=4 "$a" file2.txt | sort -k4,4) | <(awk -vf=1 "$a" file1.txt | sort) \ awk 'BEGIN {OFS = "\t"} {$4 = substr($4, 1, 5) + 0 "-" substr($4, 6, 5) + 0; print}' 

Sortie:

 0 855520 52220 33-47 10 22 -99 10 1 5432 545 33-101 10 22 -99 15.8 1 5524 5420 33-126 10 22 -99 15.5 0 5463 5420 34-133 10 22 -99 13 0 5563 5423 40-109 10 22 -99 12 1 6098 -99 40-109 10 22 -99 12 

Si vous avez omis la spécification de sortie -o (et changez le champ de $4 à $1 dans le awk final), raccourcissant ainsi la commande, voici à quoi ressemblerait la sortie (champ commun en premier):

 33-47 0 855520 52220 10 22 -99 10 33-101 1 5432 545 10 22 -99 15.8 33-126 1 5524 5420 10 22 -99 15.5 34-133 0 5463 5420 10 22 -99 13 40-109 0 5563 5423 10 22 -99 12 40-109 1 6098 -99 10 22 -99 12 

Ce qui précède fonctionne en remplissant les nombres dans le champ clé et en supprimant le trait d'union, puis annulez-le plus tard. Cela permet un sorting lexical simple.

J'étais tenté d'utiliser sort -V (version sort) au lieu d'utiliser la technique de padding. Il donne le bon ordre de sorting, mais rejette la join .