String Bash4:通过任意分隔符对字符串的子字符串(n)进行一般访问?

String Bash4:通过任意分隔符对字符串的子字符串(n)进行一般访问?,string,bash,substring,String,Bash,Substring,假设我有以下字符串:x=“数字1;数字2;数字3” 通过${x%%“;”*}成功访问第一个子字符串,通过${x%%*”}访问最后一个子字符串: 我如何访问中间部分:(例如,第2个)? 如果我有(许多…)多个零件,而只有三个零件,有没有更好的方法 换句话说:是否有一种访问字符串yyy的子字符串编号n的通用方法,由字符串xxx分隔,其中xxx是仲裁字符串/分隔符? 我已经读过了,但我特别不想迭代字符串,而是直接访问给定的子字符串 这并不是询问或拆分为数组,而是拆分为子字符串。具有固定索引: x="

假设我有以下字符串:
x=“数字1;数字2;数字3”

通过
${x%%“;”*}
成功访问第一个子字符串,通过
${x%%*”}
访问最后一个子字符串:

我如何访问中间部分:(例如,
第2个
)?
如果我有(许多…)多个零件,而只有三个零件,有没有更好的方法 换句话说:是否有一种访问字符串
yyy
的子字符串编号
n
的通用方法,由字符串
xxx
分隔,其中
xxx
是仲裁字符串/分隔符?


我已经读过了,但我特别不想迭代字符串,而是直接访问给定的子字符串

这并不是询问或拆分为数组,而是拆分为子字符串。

具有固定索引:

x="number 1;number 2;number 3"

# Split input into fields by ';' and read the 2nd field into $f2
# Note the need for the *2nd* `unused`, otherwise f2 would 
# receive the 2nd field *plus the remainder of the line*.
IFS=';' read -r unused f2 unused <<<"$x"

echo "$f2"
请注意,需要使用
-d'
一次性读取多行输入,并且需要使用另一个分隔符实例终止输入,以保留尾随的空字段;需要使用尾随的
\0
,以确保
read
的退出代码是
0

不要使用:

创建一个分隔符为
的数组

x="number 1;number 2;number 3"
_IFS=$IFS; IFS=';'
arr=($x)
IFS=$_IFS

echo ${arr[0]} # number 1
echo ${arr[1]} # number 2
echo ${arr[2]} # number 3

比Stackoverflow更快让我接受它作为正确答案;)谢谢请使用此命令断开字符串:
IFS=';'read-r-d'-a字段<@gniourf\u-gniourf:很好,我已经更新了答案(和你的链接答案的+)。可能重复这个
cut-d';'-f2@Kalanidhi只访问第二个子字符串,最后我希望对所有子字符串进行分隔访问(这实际上发生在循环中,需要对任何子字符串进行一般访问)。@dev null否,我要求将其拆分为字符串,而不是数组(这实际上发生在多维数组上的一个循环中,所以我不想要数组的子数组)。这是一种在分隔符上“拆分”字符串的坏方法(我应该说,是为了引入错误),不幸的是,这种方法分布很广,因为它是主题路径名扩展(globbing)。“修复”然后使用
set-f
(但这并不能解决所有问题,因为它仍然会连接多个连续的空字段);在这一点上,您可能会觉得自己在与shell作斗争:这是因为您使用的是反模式。链接的问题显示了拆分字符串的标准方法:
IFS=\;read-r-d''-a arr<当我说它仍然会连接多个连续的空字段时,我的意思是当与空间一起使用时,
IFS
(这里不是这种情况)。虽然在这种情况下,如果最后一个字段为空,它将删除它。@gniourf\u gniourf:globbing参数是有效的(并且必须设置和恢复两个配置项(
IFS
set-f
),最终会使此解决方案变得麻烦(虽然与
read…@mklement0相比,它可能有一些性能优势,但当
IFS
设置为空格字符时,会出现这种情况,例如空格、制表符或换行符(因为Bash以特殊的方式处理这些字符)。请尝试使用:
a='a b'
(在
a
b
之间有2个空格)然后是
IFS='';ari=($a)
。您将看到空字段被丢弃。虽然这实际上看起来像我们通常想要的,但当尝试使用
IFS=$'\n';a=($(echo a;echo;echo b))在数组中读取命令输出时,可能会令人惊讶
。这里空行没有被保留……这是好是坏并不重要;只是需要注意一些事情!@gniourf\u gniourf:完全同意,我的最新答案描述了所有这些。我的观点是:
IFS
不可避免地会出现这种行为,
($x)
approach——我现在怀疑您并非有意暗示,您只是指出了一个普遍的限制——因此我认为我们完全同意。
x="number 1;number 2;number 3"

# Split input int fields by ';' and read all resulting fields
# into an *array* (-a).
IFS=';' read -r -a fields <<<"$x"

# Access the desired field.
ndx=1
echo "${fields[ndx]}"
sep=';' 
IFS="$sep" read -r -d '' -a fields < <(printf "%s${sep}\0" "$x")    
x="number 1;number 2;number 3"
_IFS=$IFS; IFS=';'
arr=($x)
IFS=$_IFS

echo ${arr[0]} # number 1
echo ${arr[1]} # number 2
echo ${arr[2]} # number 3