it-roy-ru.com

как объединить два файла последовательно построчно

У меня есть два файла ( file1.txt & file2.txt ), файлы только примеры.

Как объединить два файла, чтобы создать файл - merge_files.txt как пример 3

Я пишу сейчас сценарий ksh, поэтому слияние можно сделать с помощью ksh, awk, sed, Perl one liner ... и т.д.

Справочная информация - почему мне нужно объединить файлы: моя цель - переименовать OLD файл (существует в первом поле) в НОВЫЙ файл (существует во втором поле), 

example1

more file1.txt

/etc/port1-192.9.200.1-255.555.255.0
/etc/port2-192.9.200.1-255.555.255.0
/etc/port3-192.9.200.1-255.555.255.0
/etc/port4-192.9.200.1-255.555.255.0
/etc/port5-192.9.200.1-255.555.255.0
.
.
.
.

example2

more file2.txt

/etc/port1-192.90.2.1-255.555.0.0
/etc/port2-192.90.2.1-255.555.0.0
/etc/port3-192.90.2.1-255.555.0.0
/etc/port4-192.90.2.1-255.555.0.0
/etc/port5-192.90.2.1-255.555.0.0
.
.
.
.

example3

 more merge_files.txt



 /etc/port1-192.9.200.1-255.555.255.0  /etc/port1-192.90.2.1-255.555.0.0
 /etc/port2-192.9.200.1-255.555.255.0  /etc/port2-192.90.2.1-255.555.0.0
 /etc/port3-192.9.200.1-255.555.255.0  /etc/port3-192.90.2.1-255.555.0.0
 /etc/port4-192.9.200.1-255.555.255.0  /etc/port4-192.90.2.1-255.555.0.0
 /etc/port5-192.9.200.1-255.555.255.0  /etc/port5-192.90.2.1-255.555.0.0
 .
 .
 .
 .
 .

example4 (структура merge_files.txt)

 first field                           second field

 OLD file                              NEW file
57
user1121951

Вы можете использовать paste для форматирования файлов рядом:

$ paste -d" " file1.txt file2.txt
/etc/port1-192.9.200.1-255.555.255.0 /etc/port1-192.90.2.1-255.555.0.0
/etc/port2-192.9.200.1-255.555.255.0 /etc/port2-192.90.2.1-255.555.0.0
/etc/port3-192.9.200.1-255.555.255.0 /etc/port3-192.90.2.1-255.555.0.0
/etc/port4-192.9.200.1-255.555.255.0 /etc/port4-192.90.2.1-255.555.0.0
/etc/port5-192.9.200.1-255.555.255.0 /etc/port5-192.90.2.1-255.555.0.0

Например.:

$ paste -d" " file1.txt file2.txt | while read from to; do echo mv "${from}" "${to}"; done
mv /etc/port1-192.9.200.1-255.555.255.0 /etc/port1-192.90.2.1-255.555.0.0
mv /etc/port2-192.9.200.1-255.555.255.0 /etc/port2-192.90.2.1-255.555.0.0
mv /etc/port3-192.9.200.1-255.555.255.0 /etc/port3-192.90.2.1-255.555.0.0
mv /etc/port4-192.9.200.1-255.555.255.0 /etc/port4-192.90.2.1-255.555.0.0
mv /etc/port5-192.9.200.1-255.555.255.0 /etc/port5-192.90.2.1-255.555.0.0

Конечно, вы хотели бы добавить некоторые проверки безопасности ([ -f "${from}" ], ...).

Отказ от ответственности: работает, только если в ваших именах файлов нет пробелов.

105
Adrian Frühwirth

Этот Perl однострочный будет отображать необходимые переименования

Perl -e 'open $f[$_-1], "file$_.txt" for 1,2; print "rename @n\n" while chomp(@n = map ''.<$_>, @f)'

Если это работает для вас, замените оператор print реальным переименованием и использованием

Perl -e 'open $f[$_-1], "file$_.txt" for 1,2; rename @n while chomp(@n = map ''.<$_>, @f)'

сделать реальное переименование

4
Borodin
paste -d " " file1.txt file2.txt

Отлично подходит для этой работы . Но если вы работаете с текстовыми файлами в среде Windows и используете вставку GNU, убедитесь, что вы преобразовали файлы в формат Unix (CR) и не используете файлы с ( CR-LF).

GNU paste, похоже, не обрабатывает форматы DOS должным образом, и синтаксический анализ непредсказуем, ожидаемый результат является ошибочным и неожиданным без предупреждений.

Вы можете использовать GVIM для их простого преобразования («Правка»/«Настройки файла»/«Формат файла»).

1
migs

Полностью несвязанные способы достижения цели ОП по переименованию пронумерованных файлов:

for f in {1..5}; do mv /etc/port$d-192.9.200.1-255.555.255.0 /etc/port$d-192.90.2.1-255.555.0.0; done

Еще одна возможность, основанная на rename

rename 's/192.9.200.1/192.90.2.1/' /etc/port[1-5]-192.9.200.1-255.555.255.0
0
Vincent Fourmond