如何使用sed仅打印文件中空行之前紧跟的行?

时间:2019-04-04 22:12:01

标签: awk sed

我有一个具有以下结构的文本文件:

bla1
bla2

bla3
bla4

bla5

因此您可以看到某些文本行之前有一个空行。

我知道sed具有两个缓冲区的概念,即模式空间缓冲区和保持空间缓冲区,因此我猜想它们需要在这里发挥作用,但是我不清楚如何指定它们以完成操作我需要。

在上面人为设计的示例中,我希望看到输出以下行:

bla3
bla5

6 个答案:

答案 0 :(得分:2)

sed用于在单独的行上执行s / old / new。每当您开始谈论缓冲区或进行与多行比较有关的任何事情时,您都在使用错误的工具。

您可以使用awk做到这一点:

$ awk -v RS= -F'\n' 'NR>1{print $1}' file
bla3
bla5

,但是如果文件中的第一行为空,则将无法打印第一行非空行,因此如果您希望将所有空格字符的行都视为空行,则可能是您想要的:

$ awk 'NF && !p{print} {p=NF}' file
bla3
bla5

,否则:

$ awk '($0!="") && (p==""){print} {p=$0}' file
bla3
bla5

即使在任何给定的非空行之前有多个空行,上述所有内容都将起作用。

要查看这三种方法之间的区别(鉴于问题中的示例输入,您将看不到):

PS1> printf '\nfoo\n      \nbar\n\netc\n' | cat -E
$
foo$
      $
bar$
$
etc$

PS1> printf '\nfoo\n      \nbar\n\netc\n' | awk -v RS= -F'\n' 'NR>1{print $1}'
etc

PS1> printf '\nfoo\n      \nbar\n\netc\n' | awk 'NF && !p{print} {p=NF}'
foo
bar
etc

PS1> printf '\nfoo\n      \nbar\n\netc\n' | awk '($0!="") && (p==""){print} {p=$0}'
foo
etc

答案 1 :(得分:1)

您可以使用保留缓冲区轻松地在空白之前打印行,如下所示:

sed -n -e '/^$/{x; p;}' -e h input

但是,我看不出将其用于您的用例的简单方法。对于您的情况,可以使用:

sed -n -e '/^$/ba' -e d -e :a -e n -e p input

但是我会用awk来做到这一点。

awk 'NR!=1{print $1}' RS= FS=\\n input-file

答案 2 :(得分:1)

awk 'p;{p=/^$/}' file

以上命令对每一行执行以下操作:

  1. 如果p1,则打印行;
  2. 如果行为空,请将p设置为1

如果由一个或多个空格组成的行也被认为是空的:

awk 'p;{p=!NF}' file

要打印每个非空行紧跟在空行之后,您可以使用以下方法:

awk 'p*!(p=/^$/)' file
  1. 如果p1并且此行不为空(1*!(0) = 1*1 = 1),则打印此行;
  2. 否则(1*!(1) = 1*0 = 00*anything = 0),什么也不打印。

请注意,此代码可能不适用于所有awks,它的可移植版本如下:

awk 'p*(/./);{p=/^$/}' file

如果由一个或多个空格组成的行也被认为是空的:

awk 'p*NF;{p=!NF}' file

herehere在线查看它们。

答案 3 :(得分:0)

如果sed / awk不是必需的,则可以使用grep来实现:

grep -A 1 '^$' input.txt  | grep -v -E '^$|--'

答案 4 :(得分:0)

您可以使用sed来匹配一系列行,并在匹配项内进行子匹配,如下所示:

# - use the "-n" option to omit printing of lines
# - match lines between a blank line (/^$/) and a non-blank one (/^./),
#   then print only the line that contains at least a character,
#   i.e, the non-blank line.
sed -ne '
/^$/,/^./ {
    /^./{ p; }
}' input.txt

答案 5 :(得分:0)

经gnu sed测试,您的数据在“ a”中:

$ sed -nE '/^$/{N;s/\n(.+)/\1/p}' a
bla3
bla5

在实际编辑中,-i选项在-n之前