Pregunta

I'm parsing a template using linux command line using pipes which has some 1-indexed pseudo-variables, I need 0-indexing. Bascially:

...{1}...{7}...

to become

...{0}...{6}...

I'd like to use one of grep, sed or awk in this order of preference. I guess grep can't do that but I'm not sure. Is such arithmetic operation even possible using any of these?

  • numbers used in the file are in range 0-9, so ignore problems like 23 becoming 12
  • no other numbers in the file, so you can even ignore the {}
  • I can do that using python, ruby, whatever but I prefer not to so stick to standard command line utils
  • other commend line utils usable with pipes with regex that I don't know are fine too

EDIT: Reworded first bullet point to clarify

¿Fue útil?

Solución

If the input allows it, you may be able to get away with simply:

tr 123456789 012345678

Note that this will replace all instances of any digit, so may not be suitable. (For example, 12 becomes 01. It's not clear from the question if you have to deal with 2 digit values.)

If you do need to handle multi-digit numbers, you could do:

perl -pe 's/\{(\d+)\}/sprintf( "{%d}", $1-1)/ge'

Otros consejos

You can use Perl.

perl -pe 's/(?<={)\d+(?=})/$&-1/ge' file.txt

If you are sure you can ignore {...}, then use

perl -pe 's/\d+/$&-1/ge' file.txt

And if index is always just one-digit number, then go with shorter one

perl -pe 's/\d/$&-1/ge' file.txt

With gawk version 4, you can write:

gawk '
    {
        n = split($0, a, /[0-9]/, seps)
        for (i=1; i<n; i++)
            printf("%s%d", a[i], seps[i]-1)
        print a[n]
    }
'

Older awks can use

awk '
    {
        while (match(substr($0,idx+1), /[0-9]/)) {
            idx += RSTART
            $0 = substr($0,1, idx-1) (substr($0,idx,1) - 1) substr($0,idx+1)
        }
        print 
    }
'

Both less elegant than the Perl one-liners.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top