Bash使用空格分隔值和双引号拆分字符串
在我的shell脚本中,有一个字符串保存所有参数Bash使用空格分隔值和双引号拆分字符串,bash,shell,Bash,Shell,在我的shell脚本中,有一个字符串保存所有参数 arg_str="arg1=ABC arg2=123 arg3= arg4=\"consecutive spaces and \\\"escaped quote\\\" shall be preserved within quotes\"" 我想按空格分割arg_str,但保留双引号中的任何内容。预期结果是: arg1=ABC arg2=123 arg3= arg4=consecutive spaces and \
arg_str="arg1=ABC arg2=123 arg3= arg4=\"consecutive spaces and \\\"escaped quote\\\" shall be preserved within quotes\""
我想按空格分割arg_str,但保留双引号中的任何内容。预期结果是:
arg1=ABC
arg2=123
arg3=
arg4=consecutive spaces and \"escaped quote\" shall be preserved within quotes
可以按双引号外的空格分割,但不能在双引号内保留连续空格
编辑
为什么我需要这个?我正在设计一个shell脚本来接受动态参数-arg name和value都是动态的,例如myscript.sh arg1=ABC arg2=123 arg3=arg4=连续空格和\escape quote\应保留在引号中。我不擅长狂欢。有人提到getopts,它似乎不适合动态args的情况。如果您想给大多数Linux/Unix发行版上可用的perl一个机会,那么它是可行的:
arg_str="arg1=ABC arg2=123 arg3= arg4=\"consecutive spaces and \\\"escaped quote\\\" shall be preserved within quotes\""
perl -pe 's/"[^"\\]*(?:\\.[^"\\]*)*"(*SKIP)(*F)|\h+/$&\n/g' <<< "$arg_str"
正则表达式详细信息:
:比赛开场
[^\\]*:匹配一个非\
?::启动一个非捕获组
\\:匹配a\
:匹配任意字符
[^\\]*:匹配一个非\
*:结束非捕获组。*表示重复此组0次或更多次
:比赛结束
*失败就像失败的否定断言,是?!
*SKIP定义了一个点,在该点之后子模式失败时,不允许正则表达式引擎回溯该点
|:或
\h+:匹配1个或多个水平空白
如果您不想要perl,那么这里有一个基于gnu awk的解决方案:
awk -v FPAT='[^[:blank:]]*"[^\\\\"]*(\\\\.[^\\\\"]*)*"|[^[:blank:]]+'
'{for (i=1; i<=NF; i++) print $i}' <<< "$arg_str"
我不知道您为什么要这样做,但这里有一个bash方法:
#!/bin/bash
#myscript.sh arg1=ABC arg2=123 arg3= arg4="consecutive spaces and \"escaped quote\" shall be preserved within quotes"
for arg in "${@}"
do
argname="${arg%%=*}"
argvalue="${arg##*=}"
parameters[$argname]="$argvalue"
done
printf "\n"
echo "${parameters[arg2]}"
问候 使用字符串进行此操作从根本上讲是不正确的。好吧,你为什么要把它放在这样一根绳子里?还有getopts。这能回答你的问题吗?我建议不要鼓励OP去解决设计问题。我无意鼓励/阻止任何设计模式。我所看到的问题是,需要使用引号和转义引号拆分输入,而这些引号和转义引号需要在引号之外的水平空格上拆分。@OP:在阅读您编辑的问题之后,该字符串似乎是作为脚本的命令行参数出现的。如果是这样,为什么不直接使用printf'\n'$@并检查输出。@anubhava是的,我用它来解析命令行动态参数。我不熟悉shell脚本,不确定它是否是一个好的解决方案。您的perl和printf版本运行良好,解决了我的问题。谢谢
arg1=ABC
arg2=123
arg3=
arg4="consecutive spaces and \"escaped quote\" shall be preserved within quotes"
#!/bin/bash
#myscript.sh arg1=ABC arg2=123 arg3= arg4="consecutive spaces and \"escaped quote\" shall be preserved within quotes"
for arg in "${@}"
do
argname="${arg%%=*}"
argvalue="${arg##*=}"
parameters[$argname]="$argvalue"
done
printf "\n"
echo "${parameters[arg2]}"