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 ワンライナーを試してみると、次のようになります。

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 "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 に答える
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 に答える