【问题标题】:Replace substring after second occurence of character bash在第二次出现字符 bash 后替换子字符串
【发布时间】:2019-07-02 11:08:42
【问题描述】:

我有这个字符串“foo1.0_1.0”,我想根据第二个“.”后面的数字加 1,这个数字可以超过一位。

这是我的尝试:

str="foo1.0_1.0"
version="${str##*.}"                 # gives 0
new_version="$((version + 1))"       # gives 1

echo "${str/${str##*.}/$new_version}"    # gives foo1.1_1.0 (desired: foo1.0_1.1)

因为它将${str##*.}的结果作为模式。

如何做到这一点?更一般地,如何在某个字符(本例中为点)第二次出现后替换子字符串?

【问题讨论】:

    标签: linux string bash replace substring


    【解决方案1】:

    使用awk,您可以使用点作为分隔符并增加第三个字段:

    awk 'BEGIN{FS=OFS="."} {$3++} 1' <<< "$str"
    

    foo1.0_1.1

    【讨论】:

      【解决方案2】:

      您也可以使用sed 喜欢:

      #!/bin/bash
      str=foo1.0_1.0
      header=$(echo $str | sed -n 's/\(.*\.\)[0-9]*/\1/p')
      ending=$(echo $str | sed -n 's/.*\.\([0-9]\)/\1/p')
      ending=$((ending + 1))
      echo $header$ending
      

      【讨论】:

      • 它有效,但我不确定regex101 你在那里做什么,你能解释一下吗? :)
      • 是的,在s/\(.*\.\)[0-9]*/\1/p 中,您将在sed 的寄存器\1 中保存\(...\) 之间的值,这对应于没有结束编号的标题部分(foo_1.0_1.)。在第二个正则表达式中,它的作用相同,但对于结束数字 (0)。
      • 原谅我的无知,但是为什么星号和点号之间需要\呢?另外,为什么在第二颗星之后有 /?
      • 不,问题我不是sed 的专家,但通常sed 中的命令是sed -e 's/ ... / ... /p'。这里s表示替代p打印
      【解决方案3】:

      您也可以使用此方法,它是您的代码的修改

      str="foo1.0_1.0"
      version="${str##*.}"                 # gives 0
      new_version="$((version + 1))"       # gives 1
      echo "${str%${version}}${new_version}"
      # gives foo1.0_1.1
      

      【讨论】:

      • @gsamaras 它从 str 中删除版本,然后将新版本附加到它
      【解决方案4】:

      带有读取和heredoc:

      str="foo1.0_1.17"
      while IFS='.' read a b c
        do
          echo $a"."$b"."$((c+1))
        done <<EOF
      $str
      EOF
      

      【讨论】:

      • 干净简单,+1。
      猜你喜欢
      • 1970-01-01
      • 2018-02-05
      • 1970-01-01
      • 2013-03-02
      • 1970-01-01
      • 2016-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多