我如何通过添加 n+number 来转换行

How can i convert lines with adding n+number

如何使用 sed 或正则表达式转换如下行?

(1,1,'country1'),(2,1,'country2'),(3,1,'country3').....

(1001,1,'country1'),(1002,1,'country2'),(1003,1,'country3')......

(1,1,'city'),(2,2,'city2'),(33,33,'city3').....

(5001,1001,'city1'),(5002,1002,'city2'),(5033,1033,'city3')......

I want 1000 + n so it should be 1000 + 1 = 1001 or 1000 + 25 = 1025 instead of 100025

这是一个相当复杂的 perl 单行代码

perl -F'[(]' -ane '
    BEGIN {@add=(shift,shift)}
    print join "(", map {
        @t = split /,/,$_,-1;
        for $i (0,1) {$t[$i] += $add[$i] if $t[$i]}
        join ",", @t
    } @F
' 5000 1000 <<END
(1,1,'city'),(22,22,'city2'),(333,333,'city3')
END
(5001,1001,'city'),(5022,1022,'city2'),(5333,1333,'city3')

通过 Perl,

$ echo "(1,1,'country1'),(2,1,'country2'),(3,1,'country3')....." | perl -pe 's/\(\K(\d+)/1000+/eg'
(1001,1,'country1'),(1002,1,'country2'),(1003,1,'country3').....
$ echo "(1,1,'city'),(2,2,'city2'),(33,33,'city3')....." | perl -pe 's/\(\K(\d+)/5000+/eg;s/,\K(\d+)/1000+/eg'
(5001,1001,'city'),(5002,1002,'city2'),(5033,1033,'city3').....

\K丢弃之前匹配的字符,e修饰符有助于对替换部分进行一些算术运算。

考虑这个例子。

's/\(\K(\d+)/1000+/eg'
  • \( 匹配文字 ( 符号。
  • \K 从考虑中丢弃先前匹配的 ( 字符。这就像一个积极的回头看。 \(\K 会写成 (?<=\()。 Next (\d+) 捕获以下一位或多位数字。现在这个数字存储在组索引 1 中。
  • 所以(加上后面的数就被这个1000+算术运算的输出匹配替换了。请注意,</code> 指的是位于组 index1 内的数字。如果存储的数字是 <code>1,那么 1000+1 会产生 1001,这是替换字符串。
  • g修饰符有助于进行全局匹配。
  • e修饰符允许替换部分的算术函数。

好吧,这有点老套(请注意,所有使用 awk 或 sed 试图绕过构建合适的解析器的方法都将是),但是如果您的文件格式与您制定的一​​样严格看,然后

awk 'BEGIN { RS = "("; ORS=""; FS = ","; OFS = FS } NF == 0 { next } {  += 5000; if(index(, "country") == 2)  += 1000; print RS [=10=] }' filename

应该可以。即

BEGIN { 
  RS  = "("                        # record separator
  ORS = ""                         # output record separator
  FS  = ","                        # field separator
  OFS = FS                         # output field separator
}
NF == 0 { next }                   # lines without fields skipped (that is the
                                   # virtual record before the first openparen)
{                                  # then for each line:
   += 5000                       # First field increased by 5000
  if(index(, "country") == 2) {  # Second field increased by 1000 if it
     += 1000                     # describes a country
  }
  print RS [=11=]                      # print the whole shebang
}

这需要一点解释。

因为 RS(,记录是 1,1,'country1'),2,1,'country2'), 等等(重要的是,包括末尾的 ),

由于 FS,,在第一条记录的示例中,字段是 11'country1') 和一个空标记.

由于 ORS 为空,awk 不会在输出时在记录之间放置记录分隔符。

由于 OFSFS 相同,字段在输出中的分隔方式与在输入中的分隔方式相同。

然后:

  print RS [=12=]

打印以逗号分隔的所有字段 (OFS = FS = ","),前面加上一个 openparen(RS 是什么),然后是输出记录分隔符——它是空的。因此格式与输入中的格式保持一致,实际上只有我们更改的字段发生了更改。

vim解决方案

对于第一种情况:只有第一个数字会增加1000:

:%s/(\zs\d\+/\=submatch(0)+1000/g

对于第二个例子:必须更改两个数字,第一个数字+5k,第二个数字+1k:

:%s/\v\(\zs(\d+),(\d+)/\=string(submatch(1)+5000).','.string(submatch(2)+1000)/g