Cryptic sed命令语法混乱

Tre*_*fer 2 regex unix sed

有人可以解释一下,这个sed命令在这里有用吗?

pkg info | sed -e 's/\([^.]*\).*/\1/' -e 's/\(.*\)-.*/\1/'
Run Code Online (Sandbox Code Playgroud)

此命令从包中删除版本号,并打印到stdout中,如下所示

yajl-2.1.0                     Portable JSON parsing and serialization library in ANSI C
youtube_dl-2018.12.03          Program for downloading videos from YouTube.com
zathura-0.4.1                  Customizable lightweight pdf viewer
zathura-pdf-poppler-0.2.9_1    Poppler render PDF plugin for Zathura PDF viewer
zip-3.0_1                      Create/update ZIP files compatible with PKZIP
zsh-5.6.2                      The Z shell
Run Code Online (Sandbox Code Playgroud)

变成这个

yajl
youtube_dl
zathura
zathura-pdf-poppler
zip
zsh
Run Code Online (Sandbox Code Playgroud)

但我很难理解这些部分([^.]*\).* \(.*\)-.*.我了解的情况\,-e,s.但这些通配符在这里看起来非常神秘.

Pus*_*shi 5

在你的正则表达式中([^.]*\).*,(它实际上是\(捕获的开始,然后[^.]*捕获除了文字点之外的每个字符并且*表示零或更多,然后\)是我们开始的关闭的标记,然后.*捕获捕获group1之后剩余的任何内容.

类似的将是\(.*\)-.*正则表达式的解释,其中\(.*\)将捕获组中贪婪地捕获所有内容,但将在最后的连字符处停止,-然后将匹配连字符并进一步.*匹配剩余文本.

为了解释一个例子,让我们来看看youtube_dl-2018.12.03.

在这里,\([^.]*\)将捕获所有内容直到点,因此它将捕获youtube_dl-2018然后剩余.*将捕获.12.03.然后它将被替换\1youtube_dl-2018将传递给下一个正则表达式的方法-e 's/\(.*\)-.*/\1/'.

然后在你的第二个正则表达式中\(.*\)-.*,\(.*\)将捕获 youtube_dl并放入group1,因为之后有一个连字符.*并将捕获剩余的文本2018.因为它被替换,\1因此最终文本将成为youtube_dl.

我相信,看到你的数据,你也可以简化你的命令,因为你的第一个正则表达式sed似乎是多余的.尝试以下命令,看看它是否输出相同的结果?

pkg info | sed -e 's/\(.*\)-.*/\1/'
Run Code Online (Sandbox Code Playgroud)

您只能使用此简化命令,因为您的数据都不包含a .之前的-命令,否则您应该使用自己的命令,该命令有两个sed规则.

另外,另一方面,如果你使用-r(或者-E for OS X),对于扩展正则表达式,你不需要转义括号,你可以编写你的正则表达式,

pkg info | sed -r 's/([^.]*).*/\1/' -r 's/(.*)-.*/\1/'
Run Code Online (Sandbox Code Playgroud)