将空行替换为上行内容

将空行替换为上行内容

如何在 Linux 计算机上将制表符分隔的文本文件中的空行替换为上面行的内容?例如:

101 abc group1
765 efg group2
345 hij group4

456 gfd group9
762 ert group7


554 fgt group11

预期输出:

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

答案1

这是一种方法awk(当为零p时保留前一行)。NF

awk 'NF {p = $0} {print p}' file

当该行不为空时,我们将该行存储到p(以供将来使用)并打印p

NF==0(对于空行)我们只打印p.

答案2

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  

解释:

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  

解释 这与上面的想法相同,但以更简洁的方式编写。我们正在使用三元运算符。由于两个条件之一始终为真(要么NF为真,要么不为真,因此三元运算符将始终返回 true),因此两种结果都会导致打印该行(除非该行为空且没有非- 已看到空行或行仅由0) 组成。但是,如果NF未设置,我们设置$0last;如果设置了,我们设置last$0。结果就是我们想要的输出。

由于上面不会打印只是 的行0,因此您可以使用 this 而不是 that 对您来说是一个问题:

awk '{! NF ? $0=last : last=$0};1' file

答案3

使用提供的输入和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 
$

注意:'/^$/{g;};h;p'显然更常见/正确地写为'/^$/g;h;p'.只是我的风格!

正如guest_7所指出的(谢谢),该sed命令也可以更简单地写为sed '/^$/g;h' infile

正如所terdon指出的,我最初没有想到的是,“空”行可能包含空格或制表符(空白)。在这种情况下,更可靠的解决方案是:

$ sed '/^\s*$/g;h' infile

支持各种语言环境的更便携的解决方案是:

$ sed '/^[[:blank:]]*$/g;h' infile

答案4

添加到现有答案:

awk 'NR<2 && !NF{next} NF{print} !NF{print line} NF{line=$0}' test

...还将处理空的第一行(通过忽略它,因为它没有先前的输入)。

相关内容