我想不出单独在 sed 中简单而优雅地做到这一点的方法。使用write-only code 可以通过sed 执行此操作,但我需要一个非常好的理由来编写类似的内容。 :-)
您仍然可以将sed 与其他工具结合使用:
$ tac test.txt | sed '/^Pattern 2$/,/^Pattern 1$/d' | tac
Pattern 1
some text to keep
nice text here
Pattern 1
another text to keep
如果您的系统上没有tac,您可以创建一个:
$ alias tac="awk '{L[i++]=\$0} END {for(j=i-1;j>=0;)print L[j--]}'"
或与主题保持一致:
$ alias tac='sed '\''1!G;h;$!d'\'
也就是说,我会在 awk 中执行此操作,如下所示:
$ awk '/Pattern 1/{printf "%s",b;b=""} {b=b $0 ORS} /Pattern 2/{b=""} END{printf "%s",b}' text.txt
Pattern 1
some text to keep
nice text here
Pattern 1
another text to keep
或分开以便于阅读/评论:
awk '
/Pattern 1/ { # If we find the start pattern,
printf "%s",b # print the buffer (or nothing if it's empty)
b="" # and empty the buffer.
}
{ # Add the current line to a buffer, with the
b=b $0 ORS # correct output record separator.
}
/Pattern 2/ { # If we find our close pattern,
b="" # just empty the buffer.
}
END { # And at the end of the file,
printf "%s",b # print the buffer if we have one.
}' test.txt
这与hek2mgl的解决方案大致相同,但排序更合理并使用ORS。 :-)
请注意,只有当Pattern 2 在文件中仅存在一次时,这两种解决方案才能正确运行。如果您有多个块,即同时包含开始和结束模式,则需要为此加倍努力。如果是这种情况,请在您的问题中提供更多详细信息。