【问题标题】:shell - replace string with incrementing valueshell - 用递增值替换字符串
【发布时间】:2017-03-03 22:20:41
【问题描述】:

我有这个字符串:

"a | a | a | a | a | a | a | a"

我想用一个递增的值替换每个“|”,如下所示:

"a0a1a2a3a4a5a6a"

我知道我可以使用 gsub 来替换字符串:

> echo "a | a | a | a | a | a | a | a" | awk '{gsub(/\ \|\ /, ++i)}1'
a1a1a1a1a1a1a1a

但 gsub 似乎只在每个换行符之后递增,所以我现在的解决方案是首先在每个“|”之后放置一个换行符,然后使用 gsub 并再次删除换行符:

> echo "a | a | a | a | a | a | a | a" | awk '{gsub(/\ \|\ /, " | \n")}1' | awk '{gsub(/\ \|\ /, ++i)}1' | tr -d '\n'
a1a2a3a4a5a6a7a

这真的很恶心......

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: shell awk


    【解决方案1】:

    如果perl 没问题:

    $ echo 'a | a | a | a | a | a | a | a' | perl -pe 's/ *\| */$i++/ge'
    a0a1a2a3a4a5a6a
    
    • *\| * 匹配 | 被零个或多个空格包围
    • e 修饰符允许在替换部分使用 Perl 代码
    • $i++使用$i的值和增量(默认值0)

    【讨论】:

      【解决方案2】:

      你可以像这样使用awk:

      s="a | a | a | a | a | a | a | a"
      
      awk -F ' *\\| *' -v OFS="" '{s=""; for(i=1; i<NF; i++) s = s $i i-1; print s $i}' <<< "$s"
      
      a0a1a2a3a4a5a6a
      
      • -F ' *\\| *' 会将| 设置为由可选空格包围的输入字段分隔符。
      • for 循环只是遍历每个字段并在每个字段之后附加字段递增位置。

      【讨论】:

        【解决方案3】:

        如果只使用sh 是一个选项,那么可能会替换,直到达到一个固定点:

        s=$1  # first argument passed to script, "a | a | a |..."
        
        n=0
        while true
        do
            prev=$s
            s=${s%" | a"}
            test "$s" = "$prev" && break
            result=$result${n}"a"
            n=$((n + 1))
        done
        echo $s$result
        

        如果这个程序存在于脚本文件digits.sh,

        $ sh digits.sh "a | a | a | a | a | a | a | a"
        a0a1a2a3a4a5a6a
        $
        

        【讨论】:

          【解决方案4】:

          使用awk的另一种解决方案

          echo "a | a | a | a | a | a | a | a" | 
          awk -v RS="[ ]+[|][ ]+" '{printf "%s%s",(f?NR-2:""),$0; f=1}'
          

          你明白了,

          a0a1a2a3a4a5a6a
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-09-20
            • 2014-08-11
            • 2015-01-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-11-03
            相关资源
            最近更新 更多