Як чергувати рядки з двох текстових файлів


77

Який найпростіший / найшвидший спосіб чергування рядків двох (або більше) текстових файлів? Приклад:

Файл 1:

line1.1
line1.2
line1.3

Файл 2:

line2.1
line2.2
line2.3

З чергуванням:

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

Звичайно, легко написати невеликий скрипт Perl, який відкриває їх обох і виконує завдання. Але мені було цікаво, чи можливо втекти за допомогою меншої кількості коду, можливо, однокласника за допомогою інструментів Unix?

Відповіді:


148
paste -d '\n' file1 file2

3
NB на деяких платформах pasteдосить обмежений - наприклад, на Solaris у вас може бути щонайбільше 12 вхідних файлів, а вихідні рядки обмежені 511 символами.
user667489

А потім використовуйте це разом із заміною процесу на прикладі типу paste -d '\n' <(find /) <(find /)і зрозумійте, наскільки це краще, ніж спочатку записувати результати у файл у будь-який спосіб, використання диска, використання пам’яті, розпаралелювання,
скасування

1
Ого paste! Повертаючись до 1979 року з AT&T UNIX 32v . Молодці, сер.
emallove

7

Ось рішення з використанням awk:

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

видає такий результат:

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

Використання awk може бути корисним, якщо ви хочете додати додаткове форматування до виводу, наприклад, якщо ви хочете позначити кожен рядок на основі того, з якого файлу він походить:

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

видає такий результат:

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

Примітка: цей код передбачає, що файл1 має довжину файлу2 або більшу за нього.

Якщо файл1 містить більше рядків, ніж файл2, і ви хочете вивести порожні рядки для файлу2 після його закінчення, додайте решту else до тесту getline:

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

або

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

3

Відповідь Сухоя вказує на корисний напрямок. Ви можете додавати номери рядків, сортувати та видаляти номери рядків:

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

Зауважте (цікаво для мене), що для правильного впорядкування потрібно трохи більше попрацювати, якщо замість статичних файлів ви використовуєте висновок команд, які можуть працювати повільніше або швидше одна за одною. У цьому випадку вам потрібно додати / відсортувати / видалити ще один тег на додаток до номерів рядків:

(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-

1

Ось спосіб графічного інтерфейсу: вставте їх у два стовпці електронної таблиці, скопіюйте всі комірки, а потім використовуйте регулярні вирази, щоб замінити вкладки на нові рядки.


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

Тут вказано, що роздільник - "." і що ми сортуємо за першим символом другого поля.


Я не розумію, як це працює. Наприклад, у вводі сортування немає двокрапки? Ви можете пояснити більше?
Frank

мій поганий, змінив ':' на '.' це просто роздільник, якщо не вказано, сортування використовує порожнє для розділення полів. man sortдля отримання додаткової інформації.
Суджой

7
Ця відповідь передбачає, що введення фактично приймає буквальну форму, описану у питанні. Я думаю, що це мало бути наочним. Можна було б трансформувати кожен вхідний файл таким чином, але це було б набагато більше передач через дані. відповідь кодактдикту краща.
Phil Miller,

@Novelocrat: Так, це просто ще один спосіб зробити це :)
Суджой
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.