只有那些外界的报价空间分割字符串 [英] Split a string only by spaces that are outside quotes
问题描述
我知道,这被问得bilion次,但我又没有找到我的具体情况下的最佳解决方案。
I know, this was asked a bilion times, but i yet did not find the optimal solution for my specific case.
我receving的字符串是这样的:
I'm receving a string like this:
VAR1="some text here" VAR2='some another text' some script --with --some=args
如何分割这样的字符串:(纯bash中最preferable)
how do i split the string like this: (most preferable in pure bash)
VAR1="some text here"
VAR2='some another text'
some script --with --some=args
设置 - $ STR
导致 VAR1 =一些
设置 - $海峡
返回整个字符串
评估设置 - $海峡
结果 VAR1 =一些文字在这里
当然,我可以报价添加到由评估
返回的字符串,但我得到高度不信任的输入,所以评估
是不是所有一个选项。
sure, i could add quotes to the string returned by eval
, but i get highly untrusted input so eval
is not a option at all.
重要提示:有可能从零到无限的增值经销商,他们可以是单或双引号
Important: there can be from zero to unlimited VARs and they can be single or double quoted
此外, VAR
是一个假名字在这里,它其实可以是任何东西。
Also, the VAR
is a fake name here, it can in fact be anything.
感谢。
推荐答案
呵,看来我迟到了:)
下面是如何我处理环境瓦尔脚本之前通过。
Here is how i'm dealing with environment vars passed before script.
首先关闭所有, escape_args
功能将难逃空间内通过增值分销商,
First off all, escape_args
function will escape spaces "inside" passed vars,
因此,如果用户通 VAR =富巴
,它将成为 VAR = foo的\\ 0040bar
。
so if user pass VAR="foo bar"
, it will become 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"
}
让测试对你输入的修改版本:
Lets test it against a modified version of your input:
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
看到的,瓦尔是空间转义和引用删除,因此声明
将正常工作。
现在你可以通过你输入的部分进行迭代。
Now you can iterate through the parts of your input.
下面是一个例子,你如何声明VAR和运行脚本:
Here is an example how you can declare vars and run the script:
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
这迭代器做两个简单的:
This iterator is doing two simple things:
- 声明一个VAR如果块匹配
SOME_VAR =
前pression - 添加块到最后的CMD否则
- declaring a var if the chunk matching
SOME_VAR=
expression - adding the chunk to the final cmd otherwise
所以输出将是:
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
这是贴近您的需求?
Is this close to your needs?
这篇关于只有那些外界的报价空间分割字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!