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


71

我有两个文件(file1.txtfile2.txt),这些文件仅是示例。

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

我现在写的是ksh脚本,因此可以用ksh,awk,sed,perl一个内衬... etc进行合并

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

例子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
.
.
.
.

例子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
.
.
.
.

例子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结构)

 first field                           second field

 OLD file                              NEW file
linux  perl  sed  awk  ksh 

两个文件的长度是否总是相同?(您的最终目标只是重命名文件,您将merge_files.txt在重命名文件后删除吗?)
MisterJ,

不,这仅是示例(长度或PATH可以更不同),文件内容也可以比较(无需删除merge_files.txt)

Answers:


123

您可以用来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}" ],...)。

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


在Linux和solaris中定义的粘贴命令?,因为我的脚本将同时在两个操作系统(Linux和solaris)上运行

paste在任何符合POSIX的系统上都可用,并且Linux和Solaris都附带了它(是Oracle网站上的Solaris手册页),因此这是一个可移植的解决方案。
AdrianFrühwirth'13

如何并排粘贴文件,而中间没有空格?即使用paste -d" " file1.txt file2.txt-没有空格分隔符?- 提前致谢!
Vikas Goel 2014年


是否有批处理(Windows)等效方法?
津巴

4

该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轻松地对其进行转换(编辑/文件设置/文件格式)


是否有批处理(Windows)等效方法?
津巴

0

完全无关的方法来实现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

基于的另一种可能性 rename

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

问题是合并文件内容,而不是重命名
Zimba

0

命令

paste file1 file2

输出

/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

0

这是在Win CMD中合并文件的示例代码:

: Count number of lines to merge
for /f "tokens=*" %i in ('find /c /v "" ^< test2.txt') do set /a n=%i<nul

: Read 2 files & merge line by line
for /l %a in (1,1,%n%) do (
for /f "tokens=*" %i in ('find /v /n "" ^< test1.txt ^| find "[%a]"') do (
for /f "tokens=*" %j in ('find /v /n "" ^< test2.txt ^| find "[%a]"') do (
set a=%i
set b=%j
set a=!a:*]=!
set b=!b:*]=!
echo:!a! -- !b!
)))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.