【发布时间】:2013-06-22 10:24:28
【问题描述】:
我想拆分一个字符串以在 Bash 中与 for 循环一起使用。例如,我有这个字符串
hello,my,name,is,mindia
我想把它分成单独的单词,这样我就可以遍历每个单词。有人可以帮帮我吗?
【问题讨论】:
-
你是怎么解决这个问题的?
我想拆分一个字符串以在 Bash 中与 for 循环一起使用。例如,我有这个字符串
hello,my,name,is,mindia
我想把它分成单独的单词,这样我就可以遍历每个单词。有人可以帮帮我吗?
【问题讨论】:
很简单的方法是使用分词到数组:
s="hello,my,name,is,mindia"
您将输入字段分隔符设置为 ,:
IFS=,
然后将字符串拆分为数组:
a=( $s )
结果:
for word in "${a[@]}"; do echo "- [$word]"; done
【讨论】:
"${a[@]}"吗?
IFS 是全局设置的...如果您忘记了它,以后可能会有惊喜。
IFS,还不如根本不定义任何数组。继续吧:s=hello,my,name,is,mindia; IFS=,; for i in $s; do echo "$i"; done
IFS=, a=( $s ) 将全局设置IFS。
使用纯bash 而不使用split(或者您的意思可能是cut):
string="hello,my,name,is,mindia"
IFS=, read -r -a array <<< "$string"
# at this point your fields are in the array array
# you can loop through the fields like so:
for field in "${array[@]}"; do
# do stuff with field field
done
# you can print the fields one per line like so
printf "%s\n" "${array[@]}"
警告。如果您尝试解析 csv 文件,它迟早会中断,例如,如果您有类似的行
field 1,"field 2 is a string, with a coma in it",field 3
好点。不过,与其他答案相比,有一个好处:如果您的字段有空格,则此方法仍然有效:
$ string="hello,this field has spaces in it,cool,it,works"
$ IFS=, read -r -a array <<< "$string"
$ printf "%s\n" "${array[@]}"
hello
this field has spaces in it
cool
it
works
另一个好处是IFS 不是全局设置的;它只为read 命令设置:当你忘记你已经全局设置IFS 时,没有什么不好的惊喜!
【讨论】:
root$ s="hello,my,name,is,mindia"
root$ for i in $(echo "$s" | tr "," "\n"); do echo $i;done
hello
my
name
is
mindia
修复了空格问题:
s="a,b,c ,d,f";
a="";
while [[ $s != $a ]] ; do
a="$(echo $s | cut -f1 -d",")";
echo $a;
s="$(echo $s | cut -f2- -d",")";
done
和输出:
a
b
c
d
f
【讨论】:
您可以使用模式替换:
s="hello,my,name,is,mindia"
for i in ${s//,/ }
do
echo $i
done
这是一个可以处理空格的版本:
while IFS= read -r -d ',' i; do
printf "%s\n" "$i"
done <<<"${s:+$s,}"
【讨论】:
s="hello,my,name,is,mindia,and this field has spaces in it,ooops"
"a,,b," 应该拆分为"a"、""、"b"、""。