2010-10-25 15 views
57

Quelle est la manière la plus simple/la plus rapide d'entrelacer les lignes de deux (ou plus) fichiers texte? Exemple:Comment entrelacer des lignes à partir de deux fichiers texte

Fichier 1:

line1.1 
line1.2 
line1.3 

Fichier 2:

line2.1 
line2.2 
line2.3 

Interleaved:

line1.1 
line2.1 
line1.2 
line2.2 
line1.3 
line2.3 

Bien sûr, il est facile d'écrire un petit script Perl qui les ouvre à la fois et ne la tâche. Mais je me demandais s'il était possible de sortir avec moins de code, peut-être un one-liner en utilisant des outils Unix?

Répondre

110
paste -d '\n' file1 file2 
+2

N.B. sur certaines plates-formes, le terme «coller» est plutôt limité - p. Sous Solaris, vous pouvez avoir au plus 12 fichiers d'entrée et les lignes de sortie sont limitées à 511 caractères. – user667489

-1
cat file1 file2 |sort -t. -k 2.1 

Voici ses précisé que le separater est "" et que nous trions le premier caractère du second champ.

+0

Je ne comprends pas comment cela fonctionne.Par exemple, il n'y a pas de deux-points dans l'entrée de tri? Pouvez-vous expliquer plus? – Frank

+0

mon mauvais, a changé le ':' en '.' c'est juste le séparateur, s'il n'est pas spécifié, le tri utilise des champs vides pour séparer les champs. "homme sort" pour plus d'informations. – Sujoy

+7

Cette réponse suppose que l'entrée prend réellement la forme littérale décrite dans la question. Je pense que c'était supposé être illustratif. Il serait possible de transformer chaque fichier d'entrée de cette façon, mais il serait beaucoup plus de passer à travers les données. La réponse de codaddict est meilleure. – Novelocrat

1

Voici une façon d'utiliser l'interface graphique: Collez-les en deux colonnes dans une feuille de calcul, copiez toutes les cellules, puis utilisez des expressions régulières pour remplacer les onglets par des retours à la ligne.

6

Voici une solution en utilisant awk:

awk '{print; if(getline < "file2") print}' file1 

produit cette sortie:

line 1 from file1 
line 1 from file2 
line 2 from file1 
line 2 from file2 
...etc 

L'utilisation awk peut être utile si vous souhaitez ajouter un formatage supplémentaire à la sortie, par exemple si vous voulez pour étiqueter chaque ligne en fonction du fichier dont elle provient:

awk '{print "1: "$0; if(getline < "file2") print "2: "$0}' file1 

produit cette sortie:

1: line 1 from file1 
2: line 1 from file2 
1: line 2 from file1 
2: line 2 from file2 
...etc 

Note: Ce code suppose que fichier_1 est supérieure ou égale à la longueur file2.

Si fichier1 contient plus de lignes que fichier2 et vous voulez afficher des lignes vides pour fichier2 après la fin, ajouter une clause else à l'épreuve getline:

awk '{print; if(getline < "file2") print; else print ""}' file1 

ou

awk '{print "1: "$0; if(getline < "file2") print "2: "$0; else print"2: "}' file1 
1

@Sujoy's answer des points dans une direction utile. Vous pouvez ajouter des numéros de ligne, trier et dépouiller les numéros de ligne:

(cat -n file1 ; cat -n file2) | sort -n | cut -f2- 

Note (d'intérêt pour moi) cela a besoin d'un peu plus de travail pour obtenir la commande à droite si au lieu de fichiers statiques que vous utilisez la sortie des commandes cela peut courir plus lentement ou plus vite que l'un l'autre. Dans ce cas, vous devez ajouter/trier/supprimer une autre étiquette en plus des numéros de ligne:

(cat -n <(command1...) | sed 's/^/1\t/' ; cat -n <(command2...) | sed 's/^/2\t/' ; cat -n <(command3) | sed 's/^/3\t/') \ 
    | sort -n | cut -f2- | sort -n | cut -f2-