【问题标题】:Bash: replace substring between quotes that contains any character typeBash:替换包含任何字符类型的引号之间的子字符串
【发布时间】:2014-09-08 20:27:21
【问题描述】:

我正在尝试使用 Bash(3.2 版)脚本编辑字符串的一部分。

例如,在 $line 中

line='<Coordinate text1="0" coordinateIndex="78?907??" anotherID="9098" yetanoherID="1.2.3" xyz:text="abc"/>'

我需要编辑坐标索引的内容(可以有任何字符/任何长度)。我的最后一次尝试(如下)没有给出错误但也没有解决问题:

echo "${line/coordinateIndex=\"\[(.*)\]\"/coordinateIndex="124"/line}"

我也试过用“)”代替“]”;还有 .+ 等等。

我正在寻找的输出是:

line='<Coordinate text1="0" coordinateIndex="124" anotherID="9098" yetanoherID="1.2.3" xyz:text="abc"/>'

我尝试了基于

的解决方案

Regex Match any string powershell

http://unix.ittoolbox.com/groups/technical-functional/shellscript-l/shell-script-to-replace-string-within-double-quotes-4107915

https://superuser.com/questions/515421/using-sed-get-substring-between-two-double-quotes

但我仍然无法解决这个问题。

任何帮助表示赞赏,谢谢!

【问题讨论】:

  • 我相信您正在寻找的是字符否定类[^"],它将捕获任何不是" 的东西。用法示例:echo "${line/coordinateIndex=\"\[^\"\]*\"/coordinateIndex="124"/line}"
  • 感谢您的回答;不幸的是,它对我不起作用......
  • 方括号转义有什么原因吗?它不应该读取 echo "${line/coordinateIndex=\"[^\"]*\"/coordinateIndex=\"124\"/line}"? 请注意在替换中 124 周围的引号中添加了转义符。
  • 这实际上将坐标索引更改为124!但不会复制该行的其余部分。我得到输出:
  • 你不能使用匹配任何字符的'*'。你需要 extglob,如下所示: shopt -s extglob; echo "${line//coordinateIndex=\"*([^\"])\"/coordinateIndex=\"124\"}";

标签: regex string bash replace


【解决方案1】:

使用perl可以轻松完成:

#!/bin/bash

str=$(cat << EOF
line='<Coordinate text1="0" coordinateIndex="78?907??" anotherID="9098" yetanoherID="1.2.3" xyz:text="abc"/>'
EOF
)

echo "$str" |perl -pe 's|(coordinateIndex=)".*?"|$1"abc"|g'

输出:

bash test.sh 
line='<Coordinate text1="0" coordinateIndex="abc" anotherID="9098" yetanoherID="1.2.3" xyz:text="abc"/>

【讨论】:

  • 行得通!谢谢!但是如何用变量 $i 替换“abc”?我尝试了 $i、${i}、$(i),但它们产生了空字符串或错误的输出。 (对 perl 完全陌生) - 谢谢。
  • 执行此操作:perl -pe 's|(coordinateIndex=)".*?"|$1"'$var'"|g' 其中$var 可以是您想要的任何变量。
【解决方案2】:

您可以使用 Bash 正则表达式匹配来做到这一点。

var=coordinateIndex
value=124
if [[ $line =~ $var=\"([0-9|\?]+)\" ]]; then
    echo ${line/$var=\"${BASH_REMATCH[1]}\"/$var=\"$value\"}
fi

这里的关键是要知道在coordinateIndex= 之后的引号之间可以找到哪种类型的字符。如果您只使用匹配任何字符的*,您最终将匹配并替换变量line 中最后一个" 之前的所有内容。

【讨论】:

  • 我明白了。感谢您的建议,效果也很好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-30
  • 2016-03-23
  • 2020-04-05
  • 2015-08-25
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
相关资源
最近更新 更多