繁体   English   中英

Linux命令sed中的正则表达式

[英]Regular Expression in Linux command sed

我有一个外壳变量:

all_apk_file="a 1 2.apk x.apk y m.apk"

我想用命令TEST替换a 1 2.apk

echo $all_apk_file | sed 's/(.*apk ){1}/TEST/g'

.*apk表示以apk结尾, {1}表示仅匹配一次,但不起作用; 我只有原始变量作为输出: a 1 2.apk x.apk y m.apk

谁能告诉我为什么?

首先 ,要启用您在sed熟悉的正则表达式,您需要使用-r开关(sed -r ...):

echo $all_apk_file | sed -r 's/(.*apk ){1}/TEST/g'
# returns TESTy m.apk

看看返回的内容: TESTy m.apk 这是因为.*贪婪 ,因此它尽可能匹配。 也就是说, .*匹配a 1 2.apk x ,并且您已经说过要替换.*apka 1 2.apk x.apk .*apk a 1 2.apk x.apk为'TEST',从而得到TESTy m.apk (请注意正则表达式中'.apk'之后的空格,这就是为什么匹配不会一直扩展到最后一个'.apk'的原因,后者后面没有空格。

通常可以将.*更改为.*? 使其不贪心 ,但sed不支持此行为。

因此,要解决此问题,只需使您的正则表达式更具限制性。

很难说出您要做什么-删除前三个单词的第三个末尾以“ .apk”结尾并替换为“ TEST”吗? 在这种情况下,可以使用正则表达式:

[a-z0-9]+ +[a-z0-9]+ +[a-z0-9]+\.apk

与“ i”开关(不区分大小写)结合使用。

您必须给出决定删除哪些内容的逻辑(前三个单词,直至第一个“ .apk”单词的任意数量的单词,等等),以便我们进一步帮助您使用正则表达式。

其次 ,将“ g”开关放入正则表达式中。 这意味着将替换所有匹配的模式,并且您似乎只希望替换第一个。 因此,删除“ g”开关。

最后 ,所有这些结合在一起:

echo $all_apk_file | sed -r 's/[a-z0-9]+ +[a-z0-9]+ +[a-z0-9]+\.apk/TEST/i'
# TEST x.apk y m.apk

这可能对您有用:

echo "$all_apk_file" | sed 's/apk/\n/;s/.*\n/TEST/'
TEST x.apk y m.apk

至于为什么您的正则表达式不起作用,请参阅@ mathematical.coffee和@Jonathan Leffler的出色解释。

s/apk/\\n/是同义s/apk/\\n/1 ,这意味着代替第一次出现的apk\\n 由于sed使用\\n作为记录分隔符,我们知道它不可能在传递给sed命令的任何初始字符串中出现。 有了这两个事实,我们就可以拆分字符串。

注意:如果您想更换第二个apks/apk/\\n/2要求。 当然,对于apk的最后一次出现, .*apk起作用。

问题的一部分是,在常规sed(){}是模式中的普通字符,直到使用反斜杠转义为止。 由于变量的值中没有括号,因此正则表达式永远不会匹配。 使用GNU sed ,您还可以使用-r标志启用扩展的正则表达式。 如果您解决了该问题,那么您将遇到.*贪婪的问题,而g修饰符实际上并不会改变任何内容:

$ echo $all_apk_file | sed 's/\(.*apk \)\{1\}/TEST/g'
TESTy m.apk
$ echo $all_apk_file | sed -r 's/(.*apk ){1}/TEST/g'
TESTy m.apk
$ echo $all_apk_file | sed -r 's/(.*apk ){1}/TEST/'
TESTy m.apk
$

它仅在此处停止,因为变量的回显值中m.apk没有空格。

现在的问题是:您要替换的是什么? 这听起来像“一切,直到单词末尾第一次出现的apk 这很容易用Perl正则表达式中的尾随上下文或非贪婪匹配来完成。 如果可以切换到Perl,请这样做。 如果不是这样,那么在正常的sed正则表达式中它就并非无关紧要。

$ echo $all_apk_file | sed 's/^[^.]* [^.][^.]*\.apk /TEST /'
TEST x.apk y m.apk
$

这将查找没有点的任何内容,其后是空格, .apk有点,以及.apk 这意味着允许的第一个点是2.apk的一个。 它适用于样本数据; 如果该变量包含:

all_apk_file="a 1.2 2.apk m.apk y.apk 37"

您需要对此进行调整以满足您的要求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM