AWK或sed方式粘贴非相邻行

时间:2016-08-28 03:52:56

标签: awk sed

$ cat file
aaa bbb ccc
ddd eee
jjj kkk lll
mmm
nnn ooo ppp

以下AWK命令会将'mmm'行粘贴到'ddd eee'行的末尾。有没有更简单的方法来使用AWK或sed?

$ awk 'FNR==NR {if (NR==4) foo=$0; next} FNR==2 {print $0" "foo; next} FNR==4 {next} 1' file file
aaa bbb ccc
ddd eee mmm
jjj kkk lll
nnn ooo ppp

澄清一下:我想在第4行末尾粘贴第4行,在'ddd eee'和'mmm'之间留一个空格。这是任务。是否有比我想出的更简单的AWK或sed解决方案?

4 个答案:

答案 0 :(得分:2)

这可以使用保留空间在sed中完成:

sed '2{N;h;N;s/\n.*\n/ /;p;g;D;}' file
  • 2{...}在第二行运行随附的命令。
  • N;h;N在模式空间中读取下两行,保留前两行。
  • s/\n.*\n/ /用中间线代替空格。
  • p;g;D打印粘贴的行,加载保留空间,然后删除 第一行(留下前一个替代品删除的那一行)。

或使用捕获(\(...\))&反向引用(\1\2等):

sed '2{N;N;s/\(\n.*\)\n\(.*\)/ \2\1/;}' file
  • 2{...}在第二行运行随附的命令。
  • N;N将下两行读入模式空间。
  • s/\(\n.*\)\n\(.*\)/ \2\1/交换第三行和第四行,连接第一行和第三行。
    • \(\n.*\)捕获第三行,包括主要换行符。
    • \n\(.*\)捕获第四行,不包括主要换行符。
    • / \2\1/用空格替换匹配的部分(第三行和第四行),然后是第二行,然后是第一个捕获组。

答案 1 :(得分:1)

这符合修改后的问题陈述的字母 - 它打印第1行,在第2行的内容后面的第4行附加第2行,然后打印第3行,然后打印第5行及以后:

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

答案 2 :(得分:0)

TXR中的解决方案:

$ 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

答案 3 :(得分:0)

这更简单:

$ 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

其他解决方案可能更快或使用更少的内存,但它们不会更简单。