Comment entrelacer les lignes de deux fichiers ou plus?

10

J'ai essayé d'obtenir la sortie de 2 fichiers dans un seul fichier. J'ai essayé la commande ci-dessous:

cat file1 file2

mais ici, les file2données s'ajoutent à file1.

Ce dont j'ai besoin, c'est de la file1première ligne suivie de la file2première ligne et de la file1deuxième ligne suivie de la file2deuxième ligne, etc.

Quelqu'un peut-il me dire comment procéder de manière simple?

user73553
la source

Réponses:

17

Il y a une application pour ça!

$ cat file1
file1 line1
file1 line2

$ cat file2
file2 line1
file2 line2

Maintenant, si vous passez ces fichiers comme arguments à paste:

$ paste -d' ' file1 file2
file1 line1 file2 line1
file1 line2 file2 line2

Si par "file1 1ère ligne suivie par file2 première ligne, et file1 deuxième ligne suivie par file2 deuxième ligne etc.", vous voulez dire que vous voulez une nouvelle ligne entre chaque ligne collée, ajustez simplement l' -doption (délimiteur).

$ paste -d'\n' file1 file2
file1 line1
file2 line1
file1 line2
file2 line2
terdon
la source
2

POSIX Awk; cela fonctionne avec une quantité arbitraire de fichiers, et les fichiers n'ont même pas besoin d'avoir la même quantité de lignes. Le script continue jusqu'à ce que tous les fichiers soient hors ligne:

BEGIN {
  do {
    br = ch = 0
    while (++ch < ARGC)
      if (getline < ARGV[ch]) {
        printf ch < ARGC - 1 ? $0 FS : $0 RS
        br = 1
      }
  } while (br)
}
Steven Penny
la source
Il y a un problème avec cela, si l'entrée contient des caractères '%', il a essayé de les évaluer dans printf. Ma mise à jour serait (je ne suis pas sûr que ce soit parfaitement correct):printf "%s", ((ch < ARGC - 1) ? $0 FS : $0 RS)
Scala William
0

Solution de bash rapide

# Takes as many file arguments as needed
function InterleaveFiles {

    local counter=0
    local hasLine=true

    while [ $hasLine == true ]; do
            hasLine=false
            for i in "$@"; do
                    line=$(awk 'NR == num_line {print; exit}' num_line=$((counter+1)) "$i")
                    if [ -n "$line" ]; then
                            echo "$line"
                    hasLine=true
                    fi
            done
            counter=$((counter+1))
    done
}

InterleaveFiles fichier1 fichier2 fichier3 fichier4

Orsiris de Jong
la source
-2
paste -d '\n' file1 file2 > file3

file1et file2sont les fichiers d'entrée et file3seront la sortie créée.

Prateek Singh
la source
1
Bienvenue sur le U&L Stack Exchange! Cette réponse est presque identique à la réponse de terdon . Dans les cas où vous pensez pouvoir améliorer une réponse, mais ne fournissez pas d'informations substantiellement nouvelles, veuillez envisager de proposer une modification à une réponse existante . Les réponses sont également réorganisées en fonction du vote, de sorte que chaque réponse doit être indépendante ou renvoyer à une autre réponse. C'est pourquoi les shell oneliners doivent être accompagnés d'une description qui explique leur fonctionnement.
Thomas Nyman