【问题标题】:Get string between strings in bash在bash中获取字符串之间的字符串
【发布时间】:2012-12-19 23:39:29
【问题描述】:

我想得到<sometag param=''>之间的字符串

我尝试使用Get any string between 2 string and assign a variable in bash 的方法来获取“x”:

 echo "<sometag param='x'><irrelevant stuff='nonsense'>" | tr "'" _ | sed -n 's/.*<sometag param=_\(.*\)_>.*/\1/p'

问题(除了效率低,因为我无法为 sed 正确转义撇号)是 sed 匹配最大值,即输出是:

 x_><irrelevant stuff=_nonsense

但正确的输出应该是最小匹配,在这个例子中只是“x”

感谢您的帮助

【问题讨论】:

  • 对于结构化数据,请使用了解结构的工具。 man xsltproc

标签: bash sed


【解决方案1】:

您可能正在寻找这样的东西:

sed -n "s/.*<sometag param='\([^']*\)'>.*/\1/p"

测试:

echo "<sometag param='x'><irrelevant stuff='nonsense'>" | sed -n "s/.*<sometag param='\([^']*\)'>.*/\1/p"

结果:

x

解释:

  • 不要使用贪婪捕获,而是使用非贪婪捕获,例如:[^']*,这意味着匹配除' 之外的任何内容任意次数。为了使模式保持不变,后面跟着:'&gt;
  • 您也可以使用双引号,这样您就不需要转义单引号。如果你想转义单引号,你可以这样做:

-

... | sed -n 's/.*<sometag param='\''\([^'\'']*\)'\''>.*/\1/p'

请注意单引号并没有真正转义。 sed 表达式停止,插入转义的单引号并重新打开 sed 表达式。把它想象成一个四字符的转义序列。


就个人而言,我会使用GNU grep。这将使解决方案略短。运行方式:

... | grep -oP "(?<=<sometag param=').*?(?='>)"

测试:

echo "<sometag param='x'><irrelevant stuff='nonsense'>" | grep -oP "(?<=<sometag param=').*?(?='>)"

结果:

x

【讨论】:

  • 谢谢,基于 grep 的解决方案正是我想要的。
  • 仅供参考:最后一个 grep 测试表达式不会在 OS X 10.11 上使用 grep 实现来执行。一般情况下,它可能不适用于 BSD。它确实适用于 Ubuntu。 :)
【解决方案2】:

在这些情况下,您不必组装正则表达式,只需使用 ' 作为字段分隔符

in="<sometag param='x'><irrelevant stuff='nonsense'>"

IFS="'" read x whatiwant y <<< "$in"            # bash
echo "$whatiwant"

awk -F\' '{print $2}' <<< "$in"                 # awk

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-29
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 2012-07-07
    • 2020-10-15
    • 2012-12-28
    相关资源
    最近更新 更多