2

我正在尝试对 acpi 命令的输出执行正则表达式替换。我的 perl 一个衬里是:

acpi | perl -F/,/ -alne 'print $F[1] if ($F[1]=~s!\s|%!!)'

上面一行的输出是,87%而我需要的输出只是87它不会%在字符串中替换。

现在acpi命令的输出是

Battery 0: Discharging, 87%, 05:54:56 remaining

的输出print $F[1]

ronnie@ronnie:~$  acpi | perl -F/,/ -alne 'print $F[1]'
 87%   #space followed by 87%#
ronnie@ronnie:~$ 

现在奇怪的是,如果我尝试相同的 perl one-liner:

echo " 86%" | perl -nle 'print if s!\s|%!!g'

它工作正常并输出86

那么,为什么它不能与 acpi 命令一起使用。

PS:我知道这可以通过使用 sed/awk 来实现,但我很感兴趣为什么我的解决方案不起作用。

4

5 回答 5

7

您的单线无法按预期工作,因为

s!\s|%!!

替换空格百分号,而不是两者

如果您希望它同时替换两者,请添加全局/g修饰符:

s!\s|%!!g

就像你在另一个例子中巧合的那样。

您也可以考虑使用字符类而不是交流发电机:

s![\s%]!!g

如果您的输出遵循您显示的格式,则最好使用简单的正则表达式:

echo Battery 0: Discharging, 87%, 05:54:56 remaining|perl -nlwe 'print /(\d+)%/'
87
于 2012-09-11T11:57:41.990 回答
2

这个按预期工作:

echo " 86%" | perl -F/,/ -alne 'print $F[1] if ($F[1]=~s!\s*(\d+)%!$1!)'
于 2012-09-11T11:57:15.390 回答
2

你缺少g修饰符

acpi | perl -F/,/ -alne 'print $F[1] if ($F[1]=~s!\s|%!!g)'
                                                    ____^
于 2012-09-11T11:57:56.213 回答
2

s!...!...!首先匹配空间,然后什么都不做。尝试添加g修饰符,如... s!\s|%!!g.

于 2012-09-11T11:58:14.453 回答
2

我试过了,效果很好。

echo "Battery 0: Discharging, 87%, 05:54:56 remaining" | perl -F, -alne '$F[1]=~s/\s|%//g;print $F[1]'
87

问题在于g修饰符。

g实际上说要替换该行中的所有匹配项,但默认行为是仅替换第一个匹配项。因此,由于开头有空格,因此$F[1]只替换空格,而忽略该行中的其余字符。

于 2012-09-11T12:01:22.063 回答