我多次使用[``]来捕获变量的命令输出。但是使用以下代码我没有得到正确的输出。
#!/bin/bash
export XLINE='($ZWP_SCRIP_NAME),$ZWP_LT_RSI_TRIGGER)R),$ZWP_RTIMER'
echo 'Original XLINE'
echo $XLINE
echo '------------------'
echo 'Extract all word with $ZWP'
#works fine
echo $XLINE | sed -e 's/\$/\n/g' | sed -e 's/.*\(ZWP[_A-Z]*\).*/\1/g' | grep ZWP
echo '------------------'
echo 'Assign all word with $ZWP to XVAR'
#XVAR doesn't get all the values
export XVAR=`echo $XLINE | sed -e 's/\$/\n/g' | sed -e 's/.*\(ZWP[_A-Z]*\).*/\1/g' | grep ZWP` #fails
echo "$XVAR"
我得到:
Original XLINE
($ZWP_SCRIP_NAME),$ZWP_LT_RSI_TRIGGER)R),$ZWP_RTIMER
------------------
Extract all word with $ZWP
ZWP_SCRIP_NAME
ZWP_LT_RSI_TRIGGER
ZWP_RTIMER
------------------
Assign all word with $ZWP to XVAR
ZWP_RTIMER
为什么XVAR没有获得所有价值?
然而,如果我使用$()来捕获out而不是``,它可以正常工作。但为什么``不工作?
答案 0 :(得分:4)
使用GNU grep可以使用此命令:
XVAR=$(grep -oP '\$\KZWP[A-Z_]+' <<< "$XLINE")
如果你传递-P
grep正在使用Perl兼容的正则表达式。这里的关键是\K
转义序列。基本上正则表达式匹配$ZWP
后跟一个或多个大写字符或下划线。 \K
之后的$
会从匹配项中删除$
本身,而其仍然需要与整个模式匹配。如果你愿意,可以称之为穷人的后卫,我喜欢它! :)
顺便说一下,grep -o
输出一行中的每个匹配,而不是仅打印与模式匹配的行。
如果您没有GNU grep或者您关心可移植性,可以使用awk
,如下所示:
XVAR=$(awk -F'$' '{sub(/[^A-Z_].*/, "", $2); print $2}' RS=',' <<< "$XLINE")
答案 1 :(得分:1)
首先,最小的变化使您的代码&#34;工作&#34;:
echo "$XLINE" | tr '$' '\n' | sed -e 's/.*\(ZWP[_A-Z]*\).*/\1/g' | grep ZWP_
tr
的使用取代了一个实际上并没有按照你的想法做的sed表达式 - 尝试查看其输出以查看。
一个明智的选择是依靠GNU grep的-o
选项。如果你不能这样做......
zwpvars=( ) # create a shell array
zwp_assignment_re='[$](ZWP_[[:alnum:]_]+)(.*)' # ...and a regex
content="$XLINE"
while [[ $content =~ $zwp_assignment_re ]]; do
zwpvars+=( "${BASH_REMATCH[1]}" ) # found a reference
content=${BASH_REMATCH[2]} # stuff the remaining content aside
done
printf 'Found variable: %s\n' "${zwpvars[@]}"