我无法实现以下行为:
input='somestring... --key1 val1 --key2 val2 --key3 val3 somestring...'
output='val1'
我尝试使用:
echo $input | sed -nE 's/.*--key1 (.*) (--.*)$/\1/p'
#but this gives 'val1 --key2 val2' instead of 'val1'
基本上,我的问题是我不知道如何告诉sed
以相反的顺序匹配模式(因此--key2
无法捕获\1
)。我相信这里有一个简单的方法,但我找不到它?
编辑:修复方法是使用:
echo $input | sed -nE 's/.*--key1 ([^(--)]*) (--.*)$/\1/p'
但我想知道针对这个用例是否存在“更好”的解决方案?
答案1
那是因为(.*)
太贪心了。
perl 具有非贪婪匹配:
perl -nE 'if (/--key1 (.*?) --/) {say $1}' <<< "$input"
如果您确实想使用正确的选项解析:
eval set -- "$(getopt --long key1:,key2:,key3: -- $input)" # $input is unquoted!
while :; do
case "$1" in
--key1) key1=$2; shift 2;;
--key2) key2=$2; shift 2;;
--key3) key3=$2; shift 2;;
--) shift; break;;
esac
done
[[ "$output" = "$key1" ]] && echo OK