ronnie
ronnie

Reputation: 1839

Replace multiple charcter using regex substitution

I am trying to perform a regex substitution on the output of acpi command. My perl one liner for this is:

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

The output of the above one liner is 87% whereas my required output is just 87 so it is not replacing % in the string.

Now the output of acpi command is

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

and the output of print $F[1] is

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

Now the strange this is if I try the same perl one-liner on:

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

It works fine and outputs 86.

So, why it is not working with acpi command.

PS: I am aware this can be achieved by using sed/awk but I am interested why my solution is not working.

Upvotes: 2

Views: 209

Answers (5)

Vijay
Vijay

Reputation: 67221

I tried this and it works perfectly.

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

Problem is with the g modifier.

g actually says to replace all the occurrences in the line, but default behaviour is to replace only the first occurrence. So since there is space at the beginning of $F[1], only space is replaced and rest of the characters in the line are ignored.

Upvotes: 2

TLP
TLP

Reputation: 67900

Your one-liner does not work as you expect because

s!\s|%!!

replaces either a whitespace or a percent sign, not both.

If you want it to replace both, add the global /g modifier:

s!\s|%!!g

Just as you coincidentally did in your other example.

You might also consider using a character class instead of alternator:

s![\s%]!!g

If your output follows the format you showed, you might be better off using a simple regex:

echo Battery 0: Discharging, 87%, 05:54:56 remaining|perl -nlwe 'print /(\d+)%/'
87

Upvotes: 6

user507077
user507077

Reputation:

Your s!...!...! matches the space first and then does nothing else. Try adding the g modifier as in ... s!\s|%!!g.

Upvotes: 2

Toto
Toto

Reputation: 91385

You're missing the g modifier

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

Upvotes: 2

perreal
perreal

Reputation: 97948

This one works as expected:

echo " 86%" | perl -F/,/ -alne 'print $F[1] if ($F[1]=~s!\s*(\d+)%!$1!)'

Upvotes: 2

Related Questions