简体   繁体   English

在grep / sed / awk中从1索引到0索引

[英]1-indexing to 0-indexing in grep/sed/awk

I'm parsing a template using linux command line using pipes which has some 1-indexed pseudo-variables, I need 0-indexing. 我正在使用Linux命令行使用管道来解析模板,该管道具有一些1索引的伪变量,我需要0索引。 Bascially: 基本上:

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

to become 成为

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

I'd like to use one of grep , sed or awk in this order of preference. 我想按此优先顺序使用grepsedawk之一。 I guess grep can't do that but I'm not sure. 我猜grep无法做到这一点,但我不确定。 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 文件中使用的数字在0-9范围内,因此请忽略诸如23变为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 我可以使用python,ruby或其他工具来做到这一点,但我不希望如此坚持使用标准命令行工具
  • other commend line utils usable with pipes with regex that I don't know are fine too 我不知道的其他可与正则表达式管道一起使用的推荐行工具也很好

EDIT : Reworded first bullet point to clarify 编辑 :改写第一个项目符号要澄清

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.) (例如, 12变为01从这个问题尚不清楚您是否必须处理两位数的值。)

If you do need to handle multi-digit numbers, you could do: 如果确实需要处理多位数的数字,则可以执行以下操作:

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

You can use Perl. 您可以使用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版本4,您可以编写:

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可以使用

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. 两者都比Perl的单行代码少优雅。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM