【问题标题】:Splitting a comma separated string into multiple words so that I can loop through each word将逗号分隔的字符串拆分为多个单词,以便我可以遍历每个单词
【发布时间】:2013-06-22 10:24:28
【问题描述】:

我想拆分一个字符串以在 Bash 中与 for 循环一起使用。例如,我有这个字符串

hello,my,name,is,mindia

我想把它分成单独的单词,这样我就可以遍历每个单词。有人可以帮帮我吗?

【问题讨论】:

  • 你是怎么解决这个问题的?

标签: bash split


【解决方案1】:

很简单的方法是使用分词到数组:

s="hello,my,name,is,mindia"

您将输入字段分隔符设置为 ,:

IFS=,

然后将字符串拆分为数组:

a=( $s )

结果:

for word in "${a[@]}"; do echo "- [$word]"; done

【讨论】:

  • 你能解释一下这个"${a[@]}"吗?
  • 请注意,使用此方法,IFS 是全局设置的...如果您忘记了它,以后可能会有惊喜。
  • 当你有数组“xxx”,并且你想迭代它的元素时,这是要使用的语法。 "${xxx[@]}" 改为 "${xxx[0]}" "${xxx[1]}" ...
  • 其实,如果你愿意在全局范围内设置IFS,还不如根本不定义任何数组。继续吧:s=hello,my,name,is,mindia; IFS=,; for i in $s; do echo "$i"; done
  • IFS=, a=( $s ) 将全局设置IFS
【解决方案2】:

使用纯 而不使用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 时,没有什么不好的惊喜!

【讨论】:

    【解决方案3】:
    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
    

    【讨论】:

    • 就像汤姆的回答一样,如果任何元素有空格,它就会中断。
    【解决方案4】:

    您可以使用模式替换:

    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"
    • OP 没有明确说这是必需的,所以我不认为这是一个主要问题。
    • 我添加了一个无论如何都可以处理空格的版本。
    • 关于您的编辑:当字符串为空或其最后一个字段为空时,您会产生副作用...
    • @gniourf_gniourf 感谢您发现错误。我修复了空字符串大小写,但我认为尾随逗号的处理是一个特性而不是一个错误。如果要支持空字段,我认为"a,,b," 应该拆分为"a""""b"""
    猜你喜欢
    • 2021-09-07
    • 2011-11-29
    • 2022-01-18
    • 2021-01-29
    • 1970-01-01
    • 2012-11-16
    • 1970-01-01
    相关资源
    最近更新 更多