Reputation: 62686
I have a file containing a lot of text and some digits describing numbers < 1 with three digits of precision. I'd like to replace those numbers with roughly equivalent integer percentages (numbers 0-99).
0.734 -> 73
0.063 -> 6
0.979 -> 97
It would be great to round properly, but not required.
I've tried the following and several variants and I can't seem to get even one match:
sed -e 's/0\.(\d\d)/&/' myfile.txt
Which I understand to mean, match the digit 0, then the decimal, capture the next two digits and have sed replace the whole match with the captured part.
Even if I get this to work, I don't know how to handle the 0.063 -> 6
case. Sure would appreciate a helping hand on this.
Upvotes: 1
Views: 1336
Reputation: 58568
This might work for you (GNU sed):
sed -r 's/0\.(([1-9][0-9])|0([0-9])).*/\2\3/' file
This uses alternation and backreferences (BR) to match the required pattern. If the first pattern matches the second BR will return that value and the third (BR) will be empty. Likewise if the second pattern in the alternation matches the the second BR will be empty and the third BR will return the required value.
Upvotes: 0
Reputation: 15304
Apart from sed
answer Zoff gave, you can use awk for better implementation (with roundings):
#round down
awk '{print int($1*100)}' myfile.txt
#0.979 -> 97
#round up
awk '{printf "%.0f\n",$1*100}' myfile.txt
#0.979 -> 98
A bash only implementation:
#round down
while read n; do result=$(bc <<< "$n*100"); echo ${result%%.*}; done < myfile.txt
#round up
while read n; do result=$(bc <<< "$n*100"); printf "%.f\n" $result; done < myfile.txt
Upvotes: 0
Reputation: 93191
sed
does support character class but use the longer POSIX name. Digits are [[:digit:]]
. It's shorter to just write [0-9]
.
Try this:
sed -E 's/0\.([0-9][0-9]).*/\1/;s/^0//' myfile.txt
The -E
flag tells it to use modern regex. There are actually 2 commands here, separated by ;
:
s/0\.([0-9][0-9]).*/\1/
: put the two digits following 0
and a dot into a capture group and replace the whole string with this capture group.
s/^0//
: remove the leading zero from the string after the above.
Upvotes: 2