2010-10-25 17 views
57

Jaki jest najłatwiejszy/najszybszy sposób na przeplatanie linii dwóch (lub więcej) plików tekstowych? Przykład:Jak przeplatać linie z dwóch plików tekstowych

Plik 1:

line1.1 
line1.2 
line1.3 

Plik 2:

line2.1 
line2.2 
line2.3 

Interleaved:

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

Oczywiście łatwo jest napisać trochę Perl skrypt, który otwiera im obu i nie zadanie. Ale zastanawiałem się, czy uda się uciec z mniejszą ilością kodu, może jednym linkiem przy użyciu narzędzi Unix?

Odpowiedz

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

N.B. na niektórych platformach "wklejanie" jest raczej ograniczone - np. w systemie Solaris możesz mieć maksymalnie 12 plików wejściowych, a linie wyjściowe są ograniczone do 511 znaków. – user667489

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

tu swój określono, że separater jest "" i że sortujemy pierwszą postać z drugiego pola.

+0

Nie rozumiem, jak to działa.Na przykład w danych wejściowych sortowania nie ma dwukropka? Czy możesz to bardziej wyjaśnić? – Frank

+0

mój zły, zmienił ":" na "." jest to tylko separator, jeśli nie jest określony, sort używa pustych pól do oddzielenia pól. 'man sort' dla więcej informacji. – Sujoy

+7

Ta odpowiedź zakłada, że ​​dane wejściowe rzeczywiście przyjmują literalną formę opisaną w pytaniu. Myślę, że miało to być ilustracyjne. Byłoby możliwe przekształcenie każdego pliku wejściowego w ten sposób, ale byłby to sposób przejścia przez dane. Odpowiedź codaddict jest lepsza. – Novelocrat

1

Oto sposób interfejsu GUI: wklej je w dwóch kolumnach w arkuszu kalkulacyjnym, skopiuj wszystkie komórki, a następnie użyj wyrażeń regularnych, aby zastąpić karty nowymi wierszami.

6

Oto rozwiązanie przy użyciu awk:

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

produkuje ten wyjściowe:

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

Korzystanie awk może być przydatne, jeśli chcesz dodać dodatkowe formatowanie do wyjścia, na przykład, jeśli chcesz aby oznaczyć każdą linię na podstawie pliku, z którego pochodzi:

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

produkuje ten wyjściowe:

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

Uwaga: Ten kod zakłada, że ​​plik1 jest większa lub równa długości plik2.

Jeśli plik1 zawiera więcej linii niż plik2 i chcesz wyjść pustych wierszy dla plik2 po jej zakończeniu, należy dodać klauzulę innego do testu getline:

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

lub

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

@Sujoy's answer punktów w użytecznym kierunku. Możesz dodać numery linii, sortowanie oraz pasek numery linii:

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

Note (odsetek do mnie), to wymaga trochę więcej pracy, aby uzyskać zamawiania prawo jeśli zamiast plików statycznych użyć wyjście poleceń które mogą działać wolniej lub szybciej od siebie. W takim przypadku musisz dodać/posortować/usunąć inny znacznik oprócz numeru wiersza:

(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- 
Powiązane problemy