如何使用 sed 打印除与范围结束模式匹配的行之外的一系列行?

发布于 2024-11-03 14:28:12 字数 563 浏览 4 评论 0原文

我想知道是否有一种 sed-only 方法可以打印一系列行,由要匹配的模式决定,除了与结束模式匹配的最后一行。

考虑以下示例。我有一个文件

line  1
line  2
line  3
ABC line  4
+ line  5
+ line  6
+ line  7
line  8
line  9
line 10
line 11
line 12

,我想获取以 ABC 开头的所有内容(包括)以及以 + 开头的所有行:

ABC line  4
+ line  5
+ line  6
+ line  7

我尝试过,

sed -n '/ABC/I,/^[^+]/ p' file

但这给出了太多行:

ABC line  4
+ line  5
+ line  6
+ line  7
line  8

省略最后一行的最简单方法是什么(仅sed)?

I wonder if there is a sed-only way to print a range of lines, determined by patterns to be matched, except the one last line matching the end pattern.

Consider following example. I have a file

line  1
line  2
line  3
ABC line  4
+ line  5
+ line  6
+ line  7
line  8
line  9
line 10
line 11
line 12

I want to get everything starting with ABC (including) and all the lines beginning with a +:

ABC line  4
+ line  5
+ line  6
+ line  7

I tried it with

sed -n '/ABC/I,/^[^+]/ p' file

but this gives one line too much:

ABC line  4
+ line  5
+ line  6
+ line  7
line  8

What's the easiest way (sed-only) to leave this last line out?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

双马尾 2024-11-10 14:28:12

可能有更好的方法,但我可以想出这个 sed 1 liner:

sed -rn '/ABC/,/^[^+]/{/(ABC|^\+)/!d;p;}' file

另一个 sed 1 liner 是

sed -n '/ABC/,/^[^+]/{x;/^$/!p;}' file

One more sed 1 liner (可能更好)

sed -n '/ABC/I{h;:A;$!n;/^+/{H;$!bA};g;p;}' file

There might be better ways but I could come up with this sed 1 liner:

sed -rn '/ABC/,/^[^+]/{/(ABC|^\+)/!d;p;}' file

Another sed 1 liner is

sed -n '/ABC/,/^[^+]/{x;/^$/!p;}' file

One more sed 1 liner (and probably better)

sed -n '/ABC/I{h;:A;$!n;/^+/{H;$!bA};g;p;}' file
嘿咻 2024-11-10 14:28:12

最简单的方法(如果有人可以通过一次调用 sed 来解决这个问题,我会学到一些新东西),是在末尾添加一个额外的 sed,即

sed -n '/ABC/I,/^[^+]/ p' file | sed '$d'
ABC line  4
+ line  5
+ line  6
+ line  7

作弊,我知道,但这就是 Unix 管道哲学的美妙之处。继续削减你的数据,直到你得到你想要的;-)

我希望这会有所帮助。

The easiest way (I'll learn something new if anyone can solve this with one call to sed), is to add an extra sed at the end, i.e.

sed -n '/ABC/I,/^[^+]/ p' file | sed '$d'
ABC line  4
+ line  5
+ line  6
+ line  7

Cheating, I know, but that is the beauty of the Unix pipe philosphy. Keep whitiling down your data until you get what you want ;-)

I hope this helps.

稀香 2024-11-10 14:28:12

这可能对您有用:

 sed '/^ABC/{:a;n;/^\(ABC\|+\)/ba};d' file

编辑:允许相邻的 ABC 部分。

This might work for you:

 sed '/^ABC/{:a;n;/^\(ABC\|+\)/ba};d' file

EDIT: to allow adjacent ABC sections.

灯下孤影 2024-11-10 14:28:12

好吧,你已经选择了你的答案。但为什么不使用 /^(ABC|\+)/ ?或者我误解了你的要求?

如果您想在搜索 ABC 后找到那些 + 行,

awk '/ABC/{f=1;print} f &&/^\+/ { print }' file

这比制作神秘的 sed 表达式更容易理解。当找到 ABC 时,设置一个标志。当找到以 + 开头的行并设置标志时,打印该行。

Well, you have selected your answer. But why aren't you using /^(ABC|\+)/ ? Or am i mis-understanding your requirement?

If you want to find those + lines AFTER a search for ABC is found

awk '/ABC/{f=1;print} f &&/^\+/ { print }' file

This is much simpler to understand than crafting cryptic sed expressions. When ABC is found, set a flag. When lines starting with + is found and flag is set, print line.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文