AWK或sed粘贴非相邻线的方式
以下AWK命令将在“ddd eee”行的末尾粘贴“mmm”行。使用AWK或sed有更简单的方法吗AWK或sed粘贴非相邻线的方式,awk,sed,Awk,Sed,以下AWK命令将在“ddd eee”行的末尾粘贴“mmm”行。使用AWK或sed有更简单的方法吗 $ cat file aaa bbb ccc ddd eee jjj kkk lll mmm nnn ooo ppp 澄清一下:我想将第4行粘贴到这个特定文件的第2行末尾,在“ddd eee”和“mmm”之间留一个空格。这就是任务。有没有比我提出的更简单的AWK或sed解决方案?解决方案: 这可以在sed中使用保留空间完成: $ txr -c '@line1 @line2 @line3 @line
$ cat file
aaa bbb ccc
ddd eee
jjj kkk lll
mmm
nnn ooo ppp
澄清一下:我想将第4行粘贴到这个特定文件的第2行末尾,在“ddd eee”和“mmm”之间留一个空格。这就是任务。有没有比我提出的更简单的AWK或sed解决方案?解决方案:
这可以在
sed
中使用保留空间完成:
$ txr -c '@line1
@line2
@line3
@line4
@(data rest)
@(output)
@line1
@line2 @line4
@line3
@ (repeat)
@ rest
@ (end)
@(end)' file
aaa bbb ccc
ddd eee mmm
jjj kkk lll
nnn ooo ppp
在第二行运行所附命令2{…}
将下两行读入模式空间,握住前两行N;HN
用空格代替中间行s/\n.*\n/
打印粘贴的行,加载保留空间,然后删除 第一行(保留前一个替换项删除的行)p;GD
\(…\)
)和反向引用(\1
,\2
等):
在第二行运行所附命令2{…}
将下两行读入图案空间N;N
交换第三行和第四行,连接第一行和第三行。s/\(\n.*\)\n\(.*\)/\2\1/
捕获第三行,包括前导换行符\(\n.*)
捕获第四行,不包括前导换行符\n\(.*)
将匹配的部分(第三行和第四行)替换为空格,然后是第二行,然后是第一个捕获组/\2\1/
sed '2{N;N;s/\(\n.*\)\n\(.*\)/ \2\1/;}' file
它比问题中的代码简单,因为它只扫描文件一次
输出:
awk 'NR == 1 || NR >= 5 { print; next }
NR == 2 { save2 = $0 }
NR == 3 { save3 = $0 }
NR == 4 { print save2, $0; print save3 }' file
这更简单:
aaa bbb ccc
ddd eee mmm
jjj kkk lll
nnn ooo ppp
其他解决方案可能更快或使用更少的内存,但它们不会更简单。您如何知道何时需要
mmm
行?你怎么知道它什么时候会出现?您是否试图确保每行上出现的字数相同?单词的数量总是三个吗?如果该行包含mmmzzz
而不是仅包含mmm
,会发生什么情况?如果有几行末尾有ttt
和uuu
,该怎么办?是否应该有ddd eee ttt
和mmm zzz uuu
?等到目前为止,这个问题还不够具体,因此无法合理地回答。第二个版本非常好。我有GNU sed,所以这是有效的:sed-r'2{N;N;s/(\N.*)\N(.*)/\2\1/;}文件你不会真的认为这比你开始使用的脚本简单吧???记住你要求的是更简单,而不是更简洁。单词simpler
很有趣。我不觉得这比两次解析文件更简单(是的,效率更高,但不简单),而且我发现这个过程要复杂得多。我猜simpler
在旁观者的眼里……问题陈述使得大多数关于解决方案优点的讨论变得无关紧要。这是一组糟糕的(奇怪的,完全不通用的)需求。这可能是一个过度简化的问题(MCVE太多)。正如你所说,旁观者眼中只有简单。您的解决方案更紧凑;我不觉得它更简单。我同意,规定得很差的要求,我理解,旁观者之眼。对我来说,当你要求代码“简单”时,必须考虑到维护的简易性,因为如果你再也不去看它,谁会在乎它是多么的简单。在这种情况下,如果将来我们不使用第2行和第4行,而是将第20行和第40行合并,该怎么办。对于OP最初发布的2-pass解决方案和我发布的修改版本,您只需将数字2更改为20,将数字4更改为40,而对于您和sed解决方案,则需要添加大量代码或进行重写。
awk 'NR == 1 || NR >= 5 { print; next }
NR == 2 { save2 = $0 }
NR == 3 { save3 = $0 }
NR == 4 { print save2, $0; print save3 }' file
aaa bbb ccc
ddd eee mmm
jjj kkk lll
nnn ooo ppp
$ awk 'FNR==NR {if (NR==4) foo=$0; next} FNR==2{$0=$0" "foo} FNR!=4' file file
aaa bbb ccc
ddd eee mmm
jjj kkk lll
nnn ooo ppp