我知道,这个问题被问了十亿次,但我还没有找到适合我的具体情况的最佳解决方案。
我收到这样的字符串:
VAR1="some text here" VAR2='some another text' some script --with --some=args
Run Code Online (Sandbox Code Playgroud)
我如何像这样分割字符串:(在纯 bash 中最好)
VAR1="some text here"
VAR2='some another text'
some script --with --some=args
Run Code Online (Sandbox Code Playgroud)
set -- $str导致VAR1="some
set -- "$str"返回整个字符串
eval set -- "$str"导致VAR1=some text here
当然,我可以在返回的字符串中添加引号eval,但我得到的输入高度不受信任,所以eval根本不是一个选项。
重要提示:VAR 的数量可以是零到无限,并且可以是单引号或双引号
另外,VAR这里是假名,实际上可以是任何名称。
谢谢。
小智 3
哈,看来我参加聚会迟到了:)
这是我处理脚本之前传递的环境变量的方式。
首先,escape_args函数将转义传递的变量“内部”的空格,
所以如果用户通过VAR="foo bar",它就会变成VAR=foo\0040bar.
function escape_args {
local str=''
local opt=''
for c in $1; do
if [[ "$c" =~ ^[[:alnum:]]+=[\"|\'] ]]; then
if [[ "${c: -1}" =~ [\"|\'] ]]; then
str="$str $( echo $c | xargs )"
else
# first opt chunk
# entering collector
opt="$c"
fi
else
if [ -z "$opt" ]; then
# not inside collector
str="$str $c"
else
# inside collector
if [[ "${c: -1}" =~ [\"|\'] ]]; then
# last opt chunk
# adding collected chunks and this last one to str
str="$str $( echo "$opt\0040$c" | xargs )"
# leaving collector
opt=''
else
# middle opt chunk
opt="$opt\0040$c"
fi
fi
fi
done
echo "$str"
}
Run Code Online (Sandbox Code Playgroud)
让我们根据输入的修改版本对其进行测试:
s="VAR1=\"some text here\" VAR2='some another text' VAR3=\"noSpaces\" VAR4='noSpacesToo' VAR5=noSpacesNoQuotes some script --with --some=args"
echo $(escape_args "$s")
VAR1=some\0040text\0040here VAR2=some\0040another\0040text VAR3=noSpaces VAR4=noSpacesToo VAR5=noSpacesNoQuotes some script --with --some=args
Run Code Online (Sandbox Code Playgroud)
看,所有变量都经过空格转义并删除了引号,因此declare可以正常工作。
现在您可以迭代输入的各个部分。
以下是如何声明变量并运行脚本的示例:
cmd=''
for c in $(escape_args "$s"); do
[[ "$c" =~ ^[[:alnum:]]+= ]] && declare "$(echo -e $c)" && continue
cmd="$cmd $c"
done
echo VAR1 is set to $VAR1
echo VAR2 is set to $VAR2
echo VAR3 is set to $VAR3
echo VAR4 is set to $VAR4
echo VAR5 is set to $VAR5
echo $cmd
Run Code Online (Sandbox Code Playgroud)
这个迭代器做了两件简单的事情:
SOME_VAR=表达式所以输出将是:
VAR1 is set to some text here
VAR2 is set to some another text
VAR3 is set to noSpaces
VAR4 is set to noSpacesToo
VAR5 is set to noSpacesNoQuotes
some script --with --some=args
Run Code Online (Sandbox Code Playgroud)
这接近您的需求吗?