Reputation: 5245
In Perl (v5.30.0), regex are evaluated as the captures, when used as parameters of print()
:
# Simplified example; the real case has more text, and the capture covers only part of it.
echo $'1\n2\n3' | perl -ne 'print /(.)/'
# 123
This is great for text extraction. I'd like to exploit the same convenience for arithmetic operations, but this doesn't work as expected:
# Attempt to compute a sum of the int value of the captures
#
echo $'1\n2\n3' | perl -ne '$tot += /(.)/; END { print $tot }'
# 3
# Attempt to print twice the int value of each capture
#
echo $'1\n2\n3' | perl -ne 'print(/(.)/ * 2)'
# 222
Using the capture variables work:
echo $'1\n2\n3' | perl -ne 'if (/(.)/) { $tot += $1 }; END { print $tot }'
# 6
However, I was curious why this happens, and if it's possible in any way to use the previous, more compact, form, in order to perform arithmetic operations on captured values.
Upvotes: 1
Views: 108
Reputation: 241988
That's because m//
returns 1 for success in scalar context (see perlop). You can enforce list context to return the matched part:
echo $'1\n2\n3' | perl -ne '$tot += (/(.)/)[0]; END { print $tot }'
Upvotes: 5
Reputation: 785531
You can use $_
to add up all of the input:
echo $'1\n2\n3' | perl -ne '$tot += $_; END { print $tot . "\n" }'
6
Or else, you can use -a
(autosplit) option to split input into fields:
echo $'1\n2\n3' | perl -ane '$tot += $F[0]; END { print $tot . "\n" }'
6
Upvotes: 1