在我的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 \"escaped quote\" shall be preserved within quotes
This answer可以按双引号之外的空格分隔,但不能保留双引号内的连续空格。
编辑
为什么我需要这个?我正在设计一个shell脚本来接受动态参数-arg名称和值都是动态的,例如myscript.sh arg1=ABC arg2=123 arg3= arg4="consecutive spaces and \"escaped quote\" shall be preserved within quotes"
。我不擅长bash。有人提到getopts
,似乎不适合动态参数的情况。
答案 0 :(得分:1)
如果您想给perl
(在大多数Linux / Unix发行版中都可以使用),那么可以这样做:
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"
arg1=ABC
arg2=123
arg3=
arg4="consecutive spaces and \"escaped quote\" shall be preserved within quotes"
RegEx详细信息:
"
:比赛开始"
[^"\\]*
:匹配不是"
而不是\
的字符(?:
:启动一个非捕获组
\\
:匹配一个\
.
:匹配任意字符[^"\\]*
:匹配不是"
而不是\
的字符)*
:结束非捕获组。 *
表示该组重复0次或更多次"
:比赛闭幕"
(*FAIL)
的行为类似于失败的否定断言,并且是(?!)
的同义词(*SKIP)
定义了一个点,当子模式稍后失败时,不允许正则表达式引擎回溯|
:或\h+
:匹配1个或多个水平空白如果您不想使用perl
,则可以使用以下基于gnu awk
的解决方案:
awk -v FPAT='[^[:blank:]]*"[^\\\\"]*(\\\\.[^\\\\"]*)*"|[^[:blank:]]+'
'{for (i=1; i<=NF; i++) print $i}' <<< "$arg_str"
arg1=ABC
arg2=123
arg3=
arg4="consecutive spaces and \"escaped quote\" shall be preserved within quotes"
答案 1 :(得分:0)
我不知道您为什么要这样做,但这是一种简便的方法:
#!/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]}"
致谢!