我正在尝试对acpi命令的输出执行正则表达式替换。我的perl one liner是:
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单线程:
echo " 86%" | perl -nle 'print if s!\s|%!!g'
工作正常并输出86
。
那么,为什么它不能使用acpi命令。
PS:我知道这可以通过使用sed / awk实现,但我感兴趣的是为什么我的解决方案无效。
答案 0 :(得分:7)
你的单行无法按预期工作,因为
s!\s|%!!
替换 空白或百分号,而不是两者。
如果您想要替换它们,请添加全局/g
修饰符:
s!\s|%!!g
正如你在其他例子中巧合的那样。
您也可以考虑使用字符类而不是交流发电机:
s![\s%]!!g
如果您的输出符合您显示的格式,那么最好使用简单的正则表达式:
echo Battery 0: Discharging, 87%, 05:54:56 remaining|perl -nlwe 'print /(\d+)%/'
87
答案 1 :(得分:2)
这个按预期工作:
echo " 86%" | perl -F/,/ -alne 'print $F[1] if ($F[1]=~s!\s*(\d+)%!$1!)'
答案 2 :(得分:2)
您错过了g
修饰符
acpi | perl -F/,/ -alne 'print $F[1] if ($F[1]=~s!\s|%!!g)'
____^
答案 3 :(得分:2)
您的s!...!...!
首先匹配该空间,然后不执行任何其他操作。尝试添加g
中的... s!\s|%!!g
修饰符。
答案 4 :(得分: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]
开头有空格,所以只替换空格,忽略行中其余字符。