Scal alternatywne linie z dwóch plików

9

Plik 1:

.tid.setnr := 1123 
.tid.setnr := 3345 
.tid.setnr := 5431
.tid.setnr := 89323

Plik2:

.tid.info := 12
.tid.info := 3
.tid.info := 44
.tid.info := 60

Plik wyjściowy:

.tid.info := 12
.tid.setnr := 1123
.tid.info := 3
.tid.setnr := 3345
.tid.info := 44
.tid.setnr := 5431
.tid.info := 60
.tid.setnr := 89323
pmaipmui
źródło
2
Proszę zawsze wspominając swój system operacyjny. Wiele standardowych narzędzi działa inaczej w różnych systemach operacyjnych, dlatego musimy wiedzieć, z czego korzystasz.
terdon

Odpowiedzi:

5

Inne rozwiązanie awk:

awk '{print; getline < "file1"; print}' file2
Glenn Jackman
źródło
5

pasteRozwiązanie jest najbardziej przenośny i najbardziej efektywne. Wspominam tylko o tej alternatywie, jeśli wolisz jej zachowanie w przypadku, gdy dwa pliki nie mają takiej samej liczby wierszy:

Z GNU sed:

sed Rfile1 file2

Jeśli file1ma mniej linii niż file2, to kiedy file1jest wyczerpany, sednie wypisze niczego dla niego (w przeciwieństwie do pustych linii dla paste).

Jeśli file1ma więcej linii niż file2, to te dodatkowe linie zostaną odrzucone (w przeciwieństwie do drukowania pustych linii do file2z paste).

$ paste a b
1       a
2       b
3
4
$ paste -d \\n a b
1
a
2
b
3

4

$ sed Rb a
1
a
2
b
3
4
$ sed Ra b
a
1
b
2
Stéphane Chazelas
źródło
4

Używanie awk( gawk, nawk, mawk):

awk 'NR==FNR {x[FNR]=$0;next} {print x[FNR]"\n"$0}' file2 file1 > outputfile
  • NR==FNR {x[FNR]=$0;next}: NR==FNRjest dopasowywany tylko wtedy, gdy bieżący numer rekordu jest równy numerowi bieżącego pliku (stąd jest dopasowywany tylko podczas przetwarzania pierwszego pliku): zapisuje aktualnie przetwarzany rekord w tablicy xo indeksie równym numerowi bieżącego pliku i pomija Aktualny zapis
  • {print x[FNR]"\n"$0}: drukuje zawartość tablicy xpod indeksem równym bieżącemu numerowi rekordu pliku, po którym następuje nowa linia i treść bieżącego rekordu
~/tmp$ cat file1
.tid.setnr := 1123
.tid.setnr := 3345
.tid.setnr := 5431
.tid.setnr := 89323
~/tmp$ cat file2
.tid.info := 12
.tid.info := 3
.tid.info := 44
.tid.info := 60
~/tmp$ awk 'NR==FNR {x[FNR]=$0;next} {print x[FNR]"\n"$0}' file2 file1
.tid.info := 12
.tid.setnr := 1123
.tid.info := 3
.tid.setnr := 3345
.tid.info := 44
.tid.setnr := 5431
.tid.info := 60
.tid.setnr := 89323
kos
źródło
Daje to wynik, ale nie dokładnie to, czego chciałem. Linie tid.info nadchodzą po liniach tid.setnr w moim pliku wyjściowym.
pmaipmui
@Nainita To właśnie pokazuje Twój przykładowy wynik.
Kos
@Nainita W każdym razie, aby zmienić kolejność wyjściową, możesz po prostu przełączyć file1i file2w poleceniu.
Kos
Tak ... Zrobiłem to samo, ale drukowałem dokładnie tak jak poprzednio. po wydrukowaniu tid.setnr był titing.info.
pmaipmui
1
@mikeserv Jednak odkąd byłem przy tym, próbowałem mawkrównież i to działa również na nim. W każdym razie jest uzasadnione nie mogę zrozumieć, dlaczego nie powinny pracować tylko na odwrót (czyli po prostu poprzez przełączanie plików). Nie chodzi o to, że awkdane wejściowe są ważne, linie są liniami. Gdyby coś nie było obsługiwane przez jego wersję, zepsułoby się po raz pierwszy. O wiele łatwiej, po prostu OP popełnił błąd, przełączając pliki wejściowe w argumentach.
Kos,
-1

Najłatwiejsze rozwiązanie podano poniżej.

cat file1 >> file2

lub

cat file2 >> file1
sachin
źródło
1
sachin, przeczytaj pytanie jeszcze raz; to dołącza zawartość jednego pliku do zawartości innego pliku. Nie łączy plików na przemian z liniami (więc jedna linia od file1tej, jedna linia od file2itd.)
don_crissti