【问题标题】:Bash string replace function similar to Javascript String.prototype.replace()Bash 字符串替换函数类似于 Javascript String.prototype.replace()
【发布时间】:2019-04-14 07:36:22
【问题描述】:

在 JS 中,我可以在替换正则表达式中的子匹配时使用函数 String.prototype.replace()。例如:

var x = 'a1b2c3'.replace(/(\d+)/g, (num) => {
    return num*num+1
})
console.log(x)
// 'a2b5c10'

我尝试过使用sed,但似乎无法在替换内部调用运算符$(())

$ echo "a1b2c3" | sed 's/\([^0-9]*\)\([0-9]\)\([^0-9]*\)/\1$((\2*\2+1))\3/g'
# Output: a$((1*1+1))b$((2*2+1))c$((3*3+1))

bash中是否有类似的工具或功能,功能类似于JS的String.replace()

【问题讨论】:

    标签: javascript bash sed sh


    【解决方案1】:

    您可以在 gawk 中使用 match()substr() 实现此功能。

    echo "a1b2c3" | awk '{
        head = ""
        tail = $0
    
        while (match(tail, /[0-9]+/)) {
            num = substr(tail, RSTART, RLENGTH)
            num = num * num + 1
            head = head substr(tail, 1, RSTART-1) num
            tail = substr(tail, RSTART + RLENGTH)
        }
    
        print head tail
    }'
    

    输出

    a2b5c10
    

    【讨论】:

      【解决方案2】:

      bash shell 确实支持本机正则表达式运算符,您可以使用 ~ 标志启用它。您需要做的就是定义一个正则表达式,获取捕获的组并用修改后的值替换它们

      str='a1b2c3'
      re='^.*([0-9]+).*([0-9]+).*([0-9]+).*$'
      if [[ $str =~ $re ]]; then
          for match in "${BASH_REMATCH[@]}"; do
              final="${str/$match/$((match*match+1))}"
          done
      fi
      printf '%s\n' "$final"
      

      [[ $str =~ $re ]] 进行正则表达式匹配并更新捕获的组数组${BASH_REMATCH[@]}。因此,对于每个元素按照它们出现的顺序,我们执行字符串替换运算符${str/old/new}。在您的情况下,替换值是数字乘以自身并加 1。

      将更多捕获组添加到正则表达式 .*([0-9]+) 以进行后续匹配。


      如果不是上面的纯 bash 解决方案,使用像 perl 这样的外部实用程序,可以这样做

      perl -pe 's/\d+/$&*$&+1/ge' <<<"$str"
      

      $&amp; 指的是字符串中捕获的数字,e 标志允许对捕获的组进行算术运算。

      【讨论】:

        猜你喜欢
        • 2018-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-08
        • 2016-10-25
        • 2012-05-30
        • 1970-01-01
        相关资源
        最近更新 更多