使用bash将字符串转换为数组,并使用引号进行分组

使用bash将字符串转换为数组,并使用引号进行分组,bash,Bash,我有一个字符串: Str='This string has "a substring"' 字符串带有逗号,因此如果我打印字符串,我会看到: echo "${Str}" This string has "a substring". 如果我输入命令: $ Tmp=( ${Str} ) $ echo "${Tmp[3]}" "a $ echo "${Tmp[4]}" Substring" 我想打印:子字符串 有什么建议吗? 我可以更改逗号,但必须将其从Str打印到Tmp如果您已经知道要查找的

我有一个字符串:

Str='This string has "a substring"'
字符串带有逗号,因此如果我打印字符串,我会看到:

echo "${Str}"

This string has "a substring". 
如果我输入命令:

$ Tmp=( ${Str} )
$ echo "${Tmp[3]}"
"a
$ echo "${Tmp[4]}"
Substring"
我想打印:
子字符串
有什么建议吗?
我可以更改逗号,但必须将其从Str打印到Tmp

如果您已经知道要查找的单词的索引,将字符串转换为数组就像使用括号一样简单:

tmp=($(echo $Str))
然后您只需
echo${tmp[4]}${tmp[5]}
即可打印不带逗号的“子字符串”。

但是,如果您已经知道子字符串是什么,为什么不从原始字符串中删除它呢

echo $Str | grep -o "a substring"
将以相同的方式返回子字符串,但不需要担心子字符串的长度或数组中单词的索引

编辑:顺便说一下,如果您只想删除任何字符串的第一个和最后一个字符,您可以这样做(bash 4.2及更高版本):

试一试:

 Str='this string has "a substring"'
 eval Tmp=( "${Str}" )

 printf "%s\n" "${Str}"
 this string has "a substring"

 printf "%s\n" "${Tmp[3]}"
 a substring

 set | grep "^Tmp"
 Tmp=([0]="this" [1]="string" [2]="has" [3]="a substring")

关于
eval
,我必须警告您,请参阅@charlesduffy的评论:仅当
Str
是在您自己的代码行之前生成的情况下使用它

此问题需要使用xargs(它将带引号的字符串保留在一起):


请注意,“无引号”项目的前导或尾随空格将被删除:

$Str='此字符串具有“子字符串”'

$IFS=$'\n'arr=($(xargs-n1你想解释哪些字符?假设Str包含
“一堆”各种引号',可能包含“转义\”字符或不匹配的引号、$metachars和$(可能是命令)。
?这应该如何分割?用数字索引无法解决问题(指语法上尊重字符串的解析方式)。我知道,我只是按照原始问题的思路添加了索引部分。我甚至指出,这不是最好的方法,而且grep方法更容易处理。
declare-p Tmp
是打印变量定义的更简单的方法,顺便说一句……我这里的问题是,使用
eval
意味着您需要相信你的内容不是恶意的(如果攻击者可以控制滑入你的变量内容,你只要把密钥交给王国)。考虑行为>代码> STR =“更大邪恶的代理:$(Touch/TMP/PWNDE.TXT))“
@CharlesDuffy我知道:当使用
read
时,或者当使用位置参数时,当它与用户提供的数据一起使用时,或者当使用位置参数时,这是批评。我们还可以想象其他情况。已经添加了Awarning。我可能会在IFS read-r-d”项时使用
;do arr+=(“$item”);完成<@CharlesDuffy很好,一个在引号内有换行符的字符串:
Str=$'string有“a\n子字符串”
将在xargs时失败:
xargs工作正常,谢谢。请解释一下为什么
-n1
部分?xargs手册页()对此我不够清楚。
 Str='this string has "a substring"'
 eval Tmp=( "${Str}" )

 printf "%s\n" "${Str}"
 this string has "a substring"

 printf "%s\n" "${Tmp[3]}"
 a substring

 set | grep "^Tmp"
 Tmp=([0]="this" [1]="string" [2]="has" [3]="a substring")
$ Str='This string has "a substring"'
$ IFS=$'\n' arr=( $(xargs -n1 <<<"$Str") )
$ printf '<%s>\n' "${arr[@]}"
<This>
<string>
<has>
<a substring>
$ echo "${Tmp[3]}"
a substring
$ Str='  This    string    has "   a substring  "'
$ IFS=$'\n' arr=( $(xargs -n1 <<<"$Str") )
$ printf '<%s>\n' "${arr[@]}"
<This>
<string>
<has>
<   a substring  >