У меня есть два файла (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
Вы можете использовать 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}" ]
,...).
Отказ от ответственности: работает только в том случае, если в ваших именах нет пробелов.
Этот однострочный 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)'
выполнить фактическое переименование
paste -d " " file1.txt file2.txt
Отлично работает для этой работы. Но если вы обрабатываете текстовые файлы в среде Windows и используете вставку GNU, обязательно преобразуйте файлы в формат Unix (CR) и не используйте файлы с (CR-LF).
Вставка GNU, похоже, не обрабатывает форматы DOS должным образом, а синтаксический анализ непредсказуем, ожидаемый вывод является непредсказуемым и неожиданным без предупреждений.
Вы можете использовать GVIM, чтобы легко их преобразовать (Edit/File Settings/File Format)
merge_files.txt
после переименования файлов?)