web-dev-qa-db-fra.com

Comment puis-je fusionner des fichiers ligne par ligne?

cat file1

foo
ice
two

cat file2

bar
cream
hundred

Sortie désirée:

foobar
icecream
twohundred

file1 et file2 auront toujours le même nombre de lignes dans mon scénario, au cas où cela faciliterait les choses.

22
TuxForLife

Le bon outil pour ce travail est probablement pastename__

paste -d '' file1 file2

Voir man paste pour plus de détails.


Vous pouvez également utiliser la commande prname__:

pr -TmJS"" file1 file2

  • -T désactive la pagination
  • -mJm erge files, J lignes complètes
  • -S"" séparer les colonnes avec une chaîne vide

Si vous vraiment vouliez le faire en utilisant pur bash Shell (non recommandé), voici ce que je suggérerais:

while IFS= read -u3 -r a && IFS= read -u4 -r b; do 
  printf '%s%s\n' "$a" "$b"
done 3<file1 4<file2

(N'incluant cela que parce que le sujet a été abordé dans les commentaires d'une autre solution proposée par pure-bash.)

34
steeldriver

À travers awk moyen:

awk '{getline x<"file2"; print $0x}' file1
  • getline x<"file2" lit la ligne entière à partir de fichier2 et reste dans la variable x .
  • print $0x imprime toute la ligne de fichier1 en utilisant $0 puis x, qui est la ligne enregistrée de fichier2 .
8
αғsнιη

paste est la voie à suivre . Si vous souhaitez vérifier d'autres méthodes, voici une solution python:

#!/usr/bin/env python2
import itertools
with open('/path/to/file1') as f1, open('/path/to/file2') as f2:
    lines = itertools.izip_longest(f1, f2)
    for a, b in lines:
        if a and b:
            print a.rstrip() + b.rstrip()
        else:
            if a:
                print a.rstrip()
            else:
                print b.rstrip()

Si vous avez peu de lignes:

#!/usr/bin/env python2
with open('/path/to/file1') as f1, open('/path/to/file2') as f2:
    print '\n'.join((a.rstrip() + b.rstrip() for a, b in Zip(f1, f2)))

Notez que pour un nombre différent de lignes, celui-ci se terminera à la dernière ligne du fichier qui se termine en premier.

4
heemayl

De plus, avec pure bash (notez que cela ignorera totalement les lignes vides):

#!/bin/bash

IFS=$'\n' GLOBIGNORE='*'
f1=($(< file1))
f2=($(< file2))
i=0
while [ "${f1[${i}]}" ] && [ "${f2[${i}]}" ]
do
    echo "${f1[${i}]}${f2[${i}]}" >> out
    ((i++))
done
while [ "${f1[${i}]}" ]
do
    echo "${f1[${i}]}" >> out
    ((i++))
done
while [ "${f2[${i}]}" ]
do
    echo "${f2[${i}]}" >> out
    ((i++))
done
3
kos

La manière de Perl, facile à comprendre:

#!/usr/bin/Perl
$filename1=$ARGV[0];
$filename2=$ARGV[1];

open(my $fh1, "<", $filename1) or die "cannot open < $filename1: $!";
open(my $fh2, "<", $filename2) or die "cannot open < $filename2: $!";

my @array1;
my @array2;

while (my $line = <$fh1>) {
  chomp $line;
  Push @array1, $line;
}
while (my $line = <$fh2>) {
  chomp $line;
  Push @array2, $line;
}

for my $i (0 .. $#array1) {
  print @array1[$i].@array2[$i]."\n";
}

Commencer avec:

./merge file1 file2

Sortie:

foobar
icecream
twohundred
2
A.B.