Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何逐行一致地合并两个文件_Linux_Perl_Sed_Awk_Ksh - Fatal编程技术网

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

Linux 如何逐行一致地合并两个文件,linux,perl,sed,awk,ksh,Linux,Perl,Sed,Awk,Ksh,我有两个文件(file1.txt&file2.txt),这些文件只是示例 如何合并这两个文件,以便创建文件-merge_files.txt,如示例3所示 我现在正在编写ksh脚本,所以可以使用ksh、awk、sed、perl一行程序等进行合并 背景-为什么我需要合并文件:我的目标是将旧文件(存在于第一个字段)重命名为新文件(存在于第二个字段) 例1 more file1.txt /etc/port1-192.9.200.1-255.555.255.0 /etc/port2-192.9.200.

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

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

我现在正在编写ksh脚本,所以可以使用ksh、awk、sed、perl一行程序等进行合并

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

例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
 .
 .
 .
 .
 .
示例4(merge_files.txt结构)


此Perl one liner将显示必要的重命名

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

要进行实际重命名

可以使用
粘贴
并排格式化文件:

$ 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
例如:

当然,您会希望进行一些安全检查(
[-f“${from}]
,…)

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

paste -d " " file1.txt file2.txt
很适合这份工作。 但是,如果您在Windows环境中处理文本文件并使用GNU粘贴,请确保将文件转换为Unix格式(CR),而不要将文件与(CR-LF)一起使用

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


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

完全不相关的方式来实现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 's/192.9.200.1/192.90.2.1/' /etc/port[1-5]-192.9.200.1-255.555.255.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

下面是在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!
)))
:计算要合并的行数

对于/f“tokens=*%i in('find/c/v”“^merge_files.txt
)不,这是唯一的示例(长度或路径可能更不同),文件内容也可能不同(无需删除merge_files.txt)linux和solaris中定义的粘贴命令,因为我的脚本将同时在两个操作系统(linux和solaris)上运行,所以在任何兼容系统上都可以使用
paste
,linux和solaris都附带了它(这是Oracle网站上的solaris手册页),所以这是一个可移植的解决方案。我如何才能将文件并排粘贴,中间没有空间?i、 例如,使用不带空格分隔符的
粘贴-d“file1.txt file2.txt”
-提前谢谢@VikasGoel
粘贴-d'\0'
(请参阅)。是否有批处理(Windows)等效方法?问题是合并文件内容,而不是重命名是否有批处理(Windows)等效方法?
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
: 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!
)))