2013-08-09 10 views
5

J'ai des fichiers txt, qui sont tous dans le même répertoire. Chacun a 2 colonnes de données. Ils ressemblent à ceci:Comment joindre plusieurs fichiers txt en fonction de la colonne?

Label1 DataA1
Label2 DataA2
Label3 DataA3

Je voudrais utiliser pour faire un joindre un grand dossier comme celui-ci.

Label1 DataA1 DataB1 DataC1
Label2 DataA2 DataB2 DataC2
Label3 DataA3 DataB3 DataC3

Actuellement, je

rejoindre fileA fileB | join - fileC

Cependant, j'ai trop de fichiers pour les rendre plus pratiques - est-il possible d'écrire une boucle pour ce type de commande?

Répondre

-1

Il suffit de mettre tous les fichiers dans un dossier et faire

join * | join - /someotherdir/fileC 
+0

Il seulement le retour s les instructions d'utilisation de la commande de jointure – Justin

+0

Ne fonctionne pas. 'join: opérande manquant après' -'' –

0

Ce script se joint à plusieurs fichiers ensemble (Les fichiers sont file*). Je reconnais que c'est moche, mais cela semble fonctionner.

2

Avec awk, vous pouvez le faire comme ceci:

awk 'NF > 0 { a[$1] = a[$1] " " $2 } END { for (i in a) { print i a[i]; } }' file* 

Si vous voulez trier vos fichiers:

find -type f -maxdepth 1 -name 'file*' -print0 | sort -z | xargs -0 awk 'NF > 0 { a[$1] = a[$1] " " $2 } END { for (i in a) { print i a[i]; } }' 

Parfois, pour (i en a) renseigne les clés pas dans l'ordre Ils ont été ajoutés afin que vous puissiez également le trier, mais ce n'est disponible que dans Gawk. L'idée de mapper des clés dans un tableau indexé pour l'ordre n'est possible que si la colonne 1 n'a pas de différences.

gawk 'NF > 0 { a[$1] = a[$1] " " $2 } END { count = asorti(a, b); for (i = 1; i <= count; ++i) { j = b[i]; print j a[j]; } }' ... 
4

Avec bash, vous pouvez créer un script qui fait une pipe récursive exec pour rejoindre:

#!/bin/bash 

if [[ $# -ge 2 ]]; then 
    function __r { 
     if [[ $# -gt 1 ]]; then 
      exec join - "$1" | __r "${@:2}" 
     else 
      exec join - "$1" 
     fi 
    } 

    __r "${@:2}" < "$1" 
fi 

Et passer les fichiers en tant que paramètres du script comme:

bash script.sh file* 

Ou un forme triée comme:

find -type f -maxdepth 1 -name 'file*' -print0 | sort -z | xargs -0 bash script.sh 
Questions connexes