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

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

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

Теперь я пишу ksh script, поэтому слияние может выполняться с помощью 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

Ответ 1

Вы можете использовать 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}" ],...).

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

Ответ 2

Этот однострочный 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)'

выполнить фактическое переименование

Ответ 3

paste -d " " file1.txt file2.txt

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

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

Вы можете использовать GVIM, чтобы легко их преобразовать (Edit/File Settings/File Format)