LiN*_*iNi 5 sed awk text-processing
如何在 Linux 机器上用上面一行的内容替换制表符分隔的文本文件中的空行?例如:
101 abc group1
765 efg group2
345 hij group4
456 gfd group9
762 ert group7
554 fgt group11
Run Code Online (Sandbox Code Playgroud)
预期输出:
101 abc group1
765 efg group2
345 hij group3
345 hij group3
456 gfd group9
762 ert group7
762 ert group7
762 ert group7
554 fgt group11
Run Code Online (Sandbox Code Playgroud)
这是一种使用awk(p在NF为零时保留前一行) 的方法。
awk 'NF {p = $0} {print p}' file
Run Code Online (Sandbox Code Playgroud)
当该行不为空时,我们将该行存储到p(以备将来使用)并打印p。
当NF==0(对于空行)我们只打印p.
在awk(请注意,这将打印第一个非空行之前的任何空行):
$ awk '{ if(! NF){$0=last}else{last=$0;}}1' file
101 abc group1
765 efg group2
345 hij group4
345 hij group4
456 gfd group9
762 ert group7
762 ert group7
762 ert group7
554 fgt group11
Run Code Online (Sandbox Code Playgroud)
说明:
NF保存字段数。如果该行为空,则没有字段,因此变量将为0。
if(! NF){$0=last}:如果字段数为0(空行),则将当前行($0)设置为变量的值last。else{last=$0;}: 如果有字段,那么这一行不为空,设置last为保存这一行的内容。1:最后唯一的一个是 awk 技巧:当某项计算结果为 true(1 或任何其他大于 0 的整数始终为 true,因为 0 为 false)时,awk 将打印当前行。所以这1相当于print $0.$ awk '! NF ? $0=last : last=$0;' file
101 abc group1
765 efg group2
345 hij group4
345 hij group4
456 gfd group9
762 ert group7
762 ert group7
762 ert group7
554 fgt group11
Run Code Online (Sandbox Code Playgroud)
解释
这与上面的想法相同,但以更简洁的方式编写。我们正在使用三元运算符。由于两个条件之一将始终为真(要么NF为真要么不为真,所以三元运算符将始终返回真),两个结果都会导致打印该行(除了该行为空且没有非- 已经看到空行或者一行只包含0)。但是,如果NF没有设置,我们设置$0为last,如果设置了,我们设置last为$0。结果就是我们想要的输出。
由于上面不会打印只是 的行,因此0您可以使用它而不是那对您来说是个问题:
awk '{! NF ? $0=last : last=$0};1' file
Run Code Online (Sandbox Code Playgroud)
使用提供的输入和sed:
$ sed -n '/^$/{g;};h;p' infile
101 abc group1
765 efg group2
345 hij group4
345 hij group4
456 gfd group9
762 ert group7
762 ert group7
762 ert group7
554 fgt group11
$
Run Code Online (Sandbox Code Playgroud)
注意:'/^$/{g;};h;p'显然更常见/正确地写为'/^$/g;h;p'. 简直就是我的风格!
正如所guest_7指出的(谢谢),该sed命令也可以更简单地写成sed '/^$/g;h' infile
正如所terdon指出的,我最初没想到的是,“空”行可能包含空格或制表符(空格)。在这种情况下,更强大的解决方案是:
$ sed '/^\s*$/g;h' infile
Run Code Online (Sandbox Code Playgroud)
支持各种语言环境的更便携的解决方案是:
$ sed '/^[[:blank:]]*$/g;h' infile
Run Code Online (Sandbox Code Playgroud)