Linux 如何逐行一致地合并两个文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16394176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:51:57  来源:igfitidea点击:

how to merge two files consistently line by line

linuxperlsedawkksh

提问by

I have two files (file1.txt& file2.txt) , files are only examples .

我有两个文件(file1.txt& file2.txt),文件只是示例。

How to merge the two files , in order to create the file - merge_files.txtas example 3

如何合并这两个文件,以创建文件-merge_files.txt作为示例3

I writing now ksh script , so merge can be done with ksh,awk,sed,perl one liner ...etc

我现在正在编写 ksh 脚本,因此可以使用 ksh、awk、sed、perl 一个 liner 等来完成合并

Background - why I need to merge the files :my target is to rename the OLD file(exist in first field) to NEW file(exist in second field) ,

背景 - 为什么我需要合并文件:我的目标是将旧文件(存在于第一个字段中)重命名为新文件(存在于第二个字段中),

example1

例子1

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

例子2

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

例子3

 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 structure)

示例 4(merge_files.txt 结构)

 first field                           second field

 OLD file                              NEW file

采纳答案by Adrian Frühwirth

You can use pasteto format the files side by side:

您可以使用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

E.g.:

例如:

$ 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

Of course you would want to throw in some safety checks ([ -f "${from}" ], ...).

当然,您会想要进行一些安全检查([ -f "${from}" ],...)。

Disclaimer: Works only if there are no spaces in your filenames.

免责声明:仅当文件名中没有空格时才有效。

回答by Borodin

This Perl one-liner will display the renames necessary

这个 Perl one-liner 将显示必要的重命名

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

If this works for you then replace the printstatement with a real rename and use

如果这对你print有用,那么用真正的重命名替换语句并使用

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

to do the actual renaming

进行实际重命名

回答by migs

paste -d " " file1.txt file2.txt

Works great for this job. But in case you are handling text files in a Windows environment and make use of GNU paste, make sure to transform the files to Unix format (CR) and not use files with (CR-LF).

非常适合这项工作。但是,如果您在 Windows 环境中处理文本文件并使用 GNU 粘贴,请确保将文件转换为 Unix 格式 (CR) 而不要使用带有 (CR-LF) 的文件。

GNU paste does not seem to handle DOS formats properly and parsing is unpredictable, the expected output is erratic and unexpected without warnings.

GNU paste 似乎不能正确处理 DOS 格式并且解析是不可预测的,预期的输出是不稳定和意外的,没有警告。

You may use GVIM to transform them easily (Edit/File Settings/File Format)

您可以使用 GVIM 轻松转换它们(编辑/文件设置/文件格式)

回答by Vincent Fourmond

Completely unrelated ways to achieve the OP's goal of renaming numbered files:

实现 OP 重命名编号文件目标的完全不相关的方法:

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

Another possibility based on rename

另一种可能性基于 rename

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

回答by user8854776

command

命令

paste file1 file2

output

输出

/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