sed - 打印和分支

sed - 打印和分支

我有一个包含表示文件类型的字符串的输入流。我想打印所有非文本文件类型或者是 PostScript(PostScript 是一种文本文件类型)。我尝试了以下 sed 表达式:

sed -n '/PostScript/pb; /text/!p'

但是,这会返回一个错误:

sed: -e expression #1, char 14: extra characters after command

bp这让我感到困惑,因为我认为在模式之后指定多个命令(例如)是可以接受的。

我可以使用以下表达式获得我想要的行为:

sed -n '/PostScript/p; /PostScript/b; /text/!p'

如何在不重复/PostScript/表达式中的模式的情况下获得我想要的行为?

答案1

让一组命令一起执行(例如,受模式匹配之类的条件影响)的常见方法是用花括号将它们分组。
使用 GNU sed

sed -n '/PostScript/{p; b}; /text/!p'

在这两种情况下都没有分组并且有任何sed分支到脚本末尾,并删除其他行:

sed -e '/PostScript/b' -e '/text/!b' -e 'd'

另外,为了记录:

bp我认为在模式之后指定多个命令(例如)是可以接受的。

地址的编辑命令(您所说的模式是上下文地址)是一回事,而substitution 标志gpwno.是另一回事。

后者的语法是

s/pattern/replacement/[flags]

换句话说,标志可以组合(例如gp7w outfile),而前者的语法是

[2addr] {editing command
editing command
...
}

换句话说,命令必须用换行符分隔(在某些情况下它们可以用分号分隔)。

答案2

POSIXly:

$ sed -n '/PostScript/p; //b
/text/!p'

POSIX 定义如果正则表达式为空,sed则其行为应如同应用最后一个命令中使用的最后一个 RE。


使用您的命令,您需要;Betweenpb才能使其与 GNU sed 一起使用:

$ sed -n '/PostScript/p; //b; /text/!p'

对于 POSIX sed,您不能使用,//b;因为;是有效的分支名称。您需要使用换行符作为命令之间的终止符。

相关内容