10

我有以下文字

abc <THIS> abc <THAT> abc <WHAT> abc

whereabc是定义明确的表达式的占位符。我想提取括号中的 3 个术语并将它们保存在 3 个单独的变量中。是否可以在不解析文本 3 次的情况下做到这一点?基本上我想捕获并以某种方式“导出”多个组。

很明显,我可以像这样提取其中一个:

VARIABLE=`echo $TEXT | sed "s_abc <\(.*\)> abc <.*> abc <.*> abc_\1_g"`

但是是否有可能在不运行 3 次的情况下获得所有 3sed个?

sed也欢迎其他(便携式)解决方案。

4

3 回答 3

11

如果有任何你知道不会出现在THISTHAT或中的字符WHAT,那么你可以这样写:

IFS=$'\t' read -r VAR1 VAR2 VAR3 \
    < <(sed 's/^abc <\(.*\)> abc <\(.*\)> abc <\(.*\)> abc$/\1\t\2\t\3/' \
             <<< "$TEXT"
       )

告诉sed在其输出中read使用该分隔符,并在其输入中使用该分隔符。

于 2012-11-05T16:56:45.127 回答
5

这可能对您有用(GNU sed 和 bash):

line='abc <THIS> abc <THAT> abc <WHAT> abc'
var=($(sed 's/[^<]*<\([^>]*\)>[^<]*/"\1" /g' <<<"$line"))
echo "first ${var[0]} second ${var[1]} third ${var[2]}"
first "THIS" second "THAT" third "WHAT"
于 2012-11-05T17:06:02.597 回答
2

无需生成进程:

var='abc <THIS> abc <THAT> abc <WHAT> abc'
var1=${var#abc <}          # Remove the leading 'abc <'.
THIS="${var1%%> abc <*}"   # Remove the longest trailing '> abc <*'.
var2="${var1#*> abc <}"    # Remove the shortest leading '*> abc <'.
THAT="${var2%%> abc <*}"   # Remove the longest trailing '> abc <*'.
var3="${var2#*> abc <}"    # Remove the shortest leading '*> abc <'.
WHAT="${var3%> abc}"       # Remove the trailing '> abc'
echo "$THIS"
echo "$THAT"
echo "$WHAT"
于 2012-11-05T20:27:15.703 回答