有人可以解释一下此sed命令在这里如何工作吗?
pkg info | sed -e 's/\([^.]*\).*/\1/' -e 's/\(.*\)-.*/\1/'
此命令从软件包中删除版本号,并像这样打印到标准输出中
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
变成这个
yajl
youtube_dl
zathura
zathura-pdf-poppler
zip
zsh
但是我很难理解([^.]*\).*
\(.*\)-.*
的各个部分。我了解\
,-e
,s
的情况。但是这些通配符在这里似乎很神秘。
答案 0 :(得分:5)
在您的正则表达式([^.]*\).*
中,实际上是(
的{{1}}是捕获 group 的开始,然后\(
捕获除文字点,[^.]*
表示零或多个,然后*
是我们开始的 group 的结束标记,然后\)
捕获捕获< em> group1 。
类似的将是对.*
正则表达式的解释,其中\(.*\)-.*
将在捕获 group 时贪婪地捕获所有内容,但会在最后一个连字符\(.*\)
处停止,然后将匹配连字符,进一步-
将匹配其余文本。
为了举例说明,让我们以.*
为例。
在这里,youtube_dl-2018.12.03
将捕获所有内容,直到点为止,因此它将捕获\([^.]*\)
,然后其余的youtube_dl-2018
将捕获.*
。然后将其替换为.12.03
,这意味着\1
将被传递到下一个正则表达式youtube_dl-2018
。
然后在第二个正则表达式-e 's/\(.*\)-.*/\1/'
,\(.*\)-.*
中捕获\(.*\)
并放入 group1 ,因为在此之后有一个连字符和{{1} }将捕获剩余的文本youtube_dl
。并且由于它被.*
取代,因此最终文本将变成2018
。
我相信,看到数据后,您还可以简化命令,因为\1
命令中的第一个正则表达式似乎很多余。试试下面的命令,看看是否输出相同的结果?
youtube_dl
您只能使用此简化命令,因为您的任何数据都不会在sed
之前包含pkg info | sed -e 's/\(.*\)-.*/\1/'
,否则,您应该使用具有两个.
规则的自己的命令。
另外,请注意,如果您使用-
(对于OS X X是 -E )对于扩展正则表达式,则不需要逃避括号,您可以将正则表达式写为
sed
答案 1 :(得分:2)
很难说:
删除所有以点或连字符开头的子字符串。
匹配并记住定界符之前的部分。
替代方法:
# Incorrect: removes from first, not last hypen:
# pkg info | sed 's/[-.].*//'
# pkg info | cut -d "-" -f1 | cut -d"." -f1
# pkg info | awk -F "-|[.]" '{print $1}'
# The dot is not needed when you remove the substring starting with the last hypen
pkg info | sed 's/-[^-]*$//'
pkg info | rev | cut -d"-" -f2- | rev
pkg info | awk -F "[.]" '{print $1}' | awk -F "[-]" -vOFS='-' 'NF>1 { NF--;print;}'
答案 2 :(得分:0)
Silly不可见文本 GNU grep
方法,
但是如果发送到文件或通过管道传递到过滤器,则会失败:
pkg info | GREP_COLORS='ms=30;30;30' grep '\-[^-]*\s.*$'
工作原理:grep
用于查找一个连字符之前的最后一个连字符
空间以及此后的所有内容,(即我们不需要的所有内容
以查看),grep
以突出显示的颜色显示,如
GREP_COLORS
个环境变量。自突出颜色
30;30;30
是黑色字体(在黑色背景上),不需要
文字不可见。
如果终端背景已经是黑色,则GREP_COLORS='ms=30
足够。
sed
方法会打印grep
regex :
pkg info | sed 's#\(^.*\)\(-[^-]*[[:space:]].*$\)#\1#'
...此方法 可以发送到管道和过滤器。使用 GNU sed
的较短版本:
pkg info | sed 's#\(^.*\)\(-.*\s.*\)#\1#'