it-swarm.com.de

Wie kann ich Dateien zeilenweise zusammenführen?

katzendatei1

foo
ice
two

katzendatei2

bar
cream
hundred

Gewünschte Ausgabe:

foobar
icecream
twohundred

datei1 und Datei2 haben in meinem Szenario immer die gleiche Anzahl von Zeilen, falls dies die Sache einfacher macht.

22
TuxForLife

Das richtige Werkzeug für diesen Job ist wahrscheinlich paste

paste -d '' file1 file2

Siehe man paste für Details.


Sie können auch den Befehl pr verwenden:

pr -TmJS"" file1 file2

wo

  • -T deaktiviert die Paginierung
  • -mJm Dateien zusammenführen, J ganze Zeilen zusammenführen
  • -S"" trennen Sie die Spalten mit einer leeren Zeichenfolge

Wenn Sie wirklich mit reiner Bash-Shell (nicht empfohlen) arbeiten wollten, dann würde ich Folgendes vorschlagen:

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

(Dies nur, weil das Thema in Kommentaren zu einer anderen vorgeschlagenen Pure-Bash-Lösung auftauchte.)

34
steeldriver

Durch awk Weg:

awk '{getline x<"file2"; print $0x}' file1
  • getline x<"file2" liest die gesamte Zeile aus file2 und enthält die Variable x .
  • print $0x druckt die gesamte Zeile aus Datei1 , indem $0 und dann x verwendet werden. Dies ist die gespeicherte Zeile von Datei2 .
8
αғsнιη

paste ist der richtige Weg . Wenn Sie andere Methoden überprüfen möchten, finden Sie hier eine python Lösung:

#!/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()

Wenn Sie nur wenige Zeilen haben:

#!/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)))

Beachten Sie, dass bei einer ungleichen Anzahl von Zeilen diese an der letzten Zeile der Datei endet, die zuerst endet.

4
heemayl

Auch mit pure bash (beachte, dass dies leere Zeilen völlig ignoriert):

#!/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

Der leicht verständliche Perl-Weg:

#!/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][email protected][$i]."\n";
}

Beginnen mit:

./merge file1 file2

Ausgabe:

foobar
icecream
twohundred
2
A.B.