sed:仅在后面跟空行替换模式

时间:2014-02-02 23:32:04

标签: sed

我需要替换文件中的模式,只有后面跟一个空行。假设我有以下文件:

test
test

test

...

以下命令会将所有test替换为xxx

cat file | sed 's/test/xxx/g'

但如果下一行为空,我只需要替换test。我尝试过匹配hex code,但这不起作用:

cat file | sed 's/test\x0a/xxx/g'

所需的输出应如下所示:

test
xxx

xxx

...

3 个答案:

答案 0 :(得分:3)

sedperlawk的建议解决方案:

<强> SED

sed -rn '1h;1!H;${g;s/test([^\n]*\n\n)/xxx\1/g;p;}' file

我从sed multiline search and replace得到了这个想法。基本上将整个文件啜饮到sed的保留空间中,并立即对整个块进行全局替换。

<强> perl的

$ perl -00 -pe 's/test(?=[^\n]*\n\n)$/xxx/m' file

-00触发段落模式,这使得perl读取块被一个或多个空行分隔(正是OP正在寻找的)。积极向前看(?=)以将替换锚定到块的最后一行。

警告: -00会将多个空行压缩成单个空行。

<强> AWK

$ awk 'NR==1 {l=$0; next}
       /^$/ {gsub(/test/,"xxx", l)}
       {print l; l=$0}
       END {print l}' file

基本上存储l中的上一行,如果当前行为空,则替换l中的模式。打印l。最后打印最后一行。

所有三种情况下的输出

test
xxx

xxx

...

答案 1 :(得分:2)

使用sed

sed -r ':a;$!{N;ba};s/test([^\n]*\n(\n|$))/xxx\1/g'

解释

:a                    # set label a
$ !{                  # if not end of file
    N                 # Add a newline to the pattern space, then append the next line of input to the pattern space
    b a               # Unconditionally branch to label. The label may be omitted, in which case the next cycle is started. 
}
#  simply, above  command :a;$!{N;ba} is used to read the whole file into pattern.
s/test([^\n]*\n(\n|$))/xxx\1/g   # replace the key word if next line is empty (\n\n) or end of line ($)

答案 2 :(得分:2)

这可能适合你(GNU sed):

sed -r '$!N;s/test(\n\s*)$/xxx\1/;P;D' file

在整个文件长度上保留一个2行的窗口,如果第二行为空,第一行包含该模式,则进行替换。