How to use awk to find and replace with calculation?

Not sure about sed/gawk, but here's one with perl

$ echo '0.2rem or 0.5rem 0.6rem' | perl -pe 's/\d+(\.\d+)?(?=rem)/$&*0.5/ge'
0.1rem or 0.25rem 0.3rem
  • \d+(\.\d+)? match digits with optional fractional part
    • (?=rem) to ensure the number is followed by rem
  • $&*0.5 multiply the number by 0.5 - the e modifier allows to use Perl code instead of string in replacement section


Applying to files:

find . -name "*.css" -exec perl -i -pe 's/\d+(\.\d+)?(?=rem)/$&*0.5/ge' {} +

See also: Why is looping over find's output bad practice?


find + GNU awk solution:

find . -type f -name "*.css" -exec gawk -i inplace \
'{ for (i=1; i<=NF; i++) 
       if ($i ~ /^[0-9]+\.[0-9]+rem/) { v=$i/2; sub(/^[0-9]+\.[0-9]+/, "", $i); $i=v $i } 
 }1' {} \;

With gawk, you could use RS that is treated as a regexp there and the fact that there, RT contains what was matched by RS. So:

find . -name '*.css' -type f -exec \
  gawk -i inplace -v RS='[0-9.]*[0-9]rem' -v ORS= 'RT{$0=$0 RT/2 "rem"};1' {} +

Tags:

Awk