如何使用sed有条件地仅删除第一行匹配的内容?

8

我可以使用sed来检查某个命令的输出(到标准输出)的第一行,并在其匹配特定模式时删除这个第一行吗?

比如说,命令的输出类似于这样:

"AB"
"CD"
"E"
"F"

I want it to become:

"CD"
"E"
"F"

但是当第一行是"GH"时,我不想删除这行。

我尝试了以下方法,但没有奏效:

<some_command> |sed '1/<pattern>/d'

壳告诉我:
sed: 0602-403 1/<pattern>/d is not a recognized function.

我只想使用sed处理第一行,保留其他行不变。

正确的语法是什么?

4个回答

8
这可能适合你:

这可能适合您:

sed -e '1!b' -e '/GH/!d' file

1
@QiangXu,是的,1是第一行,!表示如果不是,而b是一个break命令,这都意味着如果不是第一行就退出并继续下一行。对于第一行,/GH/!d的意思是如果该行不包含GH,则删除它。一些sed允许使用;字符作为连接命令的方式,在BSD或Apple上可能会有所不同。 - potong
man sed中,它只告诉我b[label] Branches to the : command bearing the label variable. If the label variable is empty, it branches to the end of the script.手册没有将b作为一个断点命令。然而,它确实可以这样工作。我错过了什么吗? - Qiang Xu
@potong,很抱歉,我不明白你想说什么。也许我的评论不够清晰。这个sed脚本如果不是第一行,则跳过所有其他命令。否则,如果匹配模式,则删除该行。如果您的脚本唯一目的就是这样做,那么这种方法是有效的。另一方面,1 { /pattern/ d }让您可以将其他命令与输入的其余部分组合在一起。 - CervEd
@CervEd 我的错而不是你的错。解决方案是独立的,不能与其他sed命令一起使用。对于GNU sed,类似于 sed '1{/GH/!d}; more sed commands' file 的东西就足够了,但是 {};在所有变体的sed中的行为都不相同。 - potong
@potong,这是一个公正的观点。我想如果它具有更好的兼容性,把它传递到另一个sed中可能是一个有效的解决方案。 - CervEd
显示剩余2条评论

7
你想引用第一行,然后说删除:
$ sed '1 d' file

如果你知道想要删除哪一行,就不需要任何模式。

使用模式时,请使用以下语法:

$ sed '0,/pattern/ d' file

2
不,我想删除第一行,只有在它符合特定的模式时才删除。 - Qiang Xu
1
啊!是的,你需要一个命令,比如p:sed /pattern1/p file -- 如果s命令有效,那么它应该是一个很好的匹配...我们能看到实际的模式吗?(你能把它添加到你的帖子中吗?)0,/pattern/地址对我很有效! - Alexis Wilke
1
啊!你没有说明它是AIX。是的...这些地址支持是一些GNU扩展。我不确定在更标准的sed上是否有效。 - Alexis Wilke
1
地址0在POSIX上不起作用,这是GNU的一个特性。 POSIX sed地址范围必须匹配至少2行,因为它在第一行上打开一个标志并在第二行上关闭它。请参见: https://www.gnu.org/software/sed/manual/html_node/Addresses.html https://www.grymoire.com/Unix/Sed.html#toc-uh-29 - dosentmatter
1
@dosentmatter 1 { /pattern/ d } 可能是吗? - CervEd
显示剩余4条评论

4
这是你想要的内容:
$ sed '1{/"GH"/!d}' file

但是它不起作用:sed: 0602-404 函数1{/<pattern>/d}无法解析。 我以“GH”为例,并想专注于需要匹配的模式。这就是为什么我使用了 d 而不是 !d 的原因。 - Qiang Xu
然后你有一个过时的sed。尝试在“{”之后和“}”之前放置换行符。 - jthill
@jthill: 依然无法工作:sed: 0602-404 函数 1{\n/<pattern>/d\n} 无法解析。 我的sed是来自 AIX 机器,而不是 GNU 的,:( - Qiang Xu
1
对于BSD sed,您需要在括号中的命令后加上分号:sed '1{/"GH"/!d;}' file 可以工作。 - gogstad

3
sed '1{/<pattern>/{/GH/!d}}' input

您的表达式中的错误可以通过以下方式修复:
sed '1{/<pattern>/d}' input

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接