循环逗号分隔的shell变量

Ram*_*n K 80 unix shell loops for-loop cut

假设我有一个Unix shell变量,如下所示

variable=abc,def,ghij
Run Code Online (Sandbox Code Playgroud)

我想使用for循环提取所有值(abc,defghij)并将每个值传递给过程.

该脚本应允许从中提取任意数量的逗号分隔值$variable.

ner*_*ric 110

不搞乱IFS
不调用外部命令

variable=abc,def,ghij
for i in ${variable//,/ }
do
    # call your procedure/other scripts here below
    echo "$i"
done
Run Code Online (Sandbox Code Playgroud)

使用bash字符串操作http://www.tldp.org/LDP/abs/html/string-manipulation.html

  • 小警告 - 如果`$ i`中的任何值包含空格,它们将被拆分(这可能是它以逗号分隔而不是以空格分隔的方式传递的原因) (11认同)
  • @anandhu 确保您正在运行“sh”或“bash” (5认同)
  • 避免弄乱'IFS`的好建议! (4认同)
  • 如果以前的函数改变了IFS设置,那么这不起作用......将其更改为:`for $ in $ {variable //,/ $ IFS} do; 回声"$ i"; done` (4认同)
  • 关于这一点的好处是你可以使用不同的分隔符嵌套多个循环.好建议! (3认同)
  • 我不知道为什么有这么多赞成票,这个循环只运行一次。尝试在循环内添加另一个 echo 语句并检查输出 (3认同)
  • 当我尝试这种方法时,我收到错误消息“替换错误”。 (2认同)

ana*_*ron 100

您可以使用以下脚本动态遍历变量,无论它有多少个字段,只要它只用逗号分隔即可.

variable=abc,def,ghij
for i in $(echo $variable | sed "s/,/ /g")
do
    # call your procedure/other scripts here below
    echo "$i"
done
Run Code Online (Sandbox Code Playgroud)

而不是echo "$i"上面的调用,在for循环内部dodone内部之间,您可以调用您的过程proc "$i".


更新:如果变量的值不包含空格,则上述代码段有效.如果您有这样的要求,请使用其中一个可以更改的解决方案,IFS然后解析您的变量.


希望这可以帮助.

  • 如果`$ variable`包含空格,这不起作用,例如`variable = ab,c,d` =>打印4行(a | b | c | d)而不是3(ab | c | d) (8认同)

fed*_*qui 48

如果设置不同的字段分隔符,则可以直接使用for循环:

IFS=","
for v in $variable
do
   # things with "$v" ...
done
Run Code Online (Sandbox Code Playgroud)

您还可以将值存储在数组中,然后按照如何在Bash中的分隔符上拆分字符串中的指示循环它:

IFS=, read -ra values <<< "$variable"
for v in "${values[@]}"
do
   # things with "$v"
done
Run Code Online (Sandbox Code Playgroud)

测试

$ variable="abc,def,ghij"
$ IFS=","
$ for v in $variable
> do
> echo "var is $v"
> done
var is abc
var is def
var is ghij
Run Code Online (Sandbox Code Playgroud)

您可以在此解决方案中找到更广泛的方法,如何迭代逗号分隔列表并为每个条目执行命令.

第二种方法的例子:

$ IFS=, read -ra vals <<< "abc,def,ghij"
$ printf "%s\n" "${vals[@]}"
abc
def
ghij
$ for v in "${vals[@]}"; do echo "$v --"; done
abc --
def --
ghij --
Run Code Online (Sandbox Code Playgroud)

  • 当有人真正知道如何使用shell时,让我高兴,而不是将一堆binutils连接在一起. (3认同)
  • 您是否必须将“IFS”设置回之前的值? (3认同)

小智 12

我认为从语法上讲,这更干净,并且也通过了 shell 检查 linting

variable=abc,def,ghij
for i in ${variable//,/ }
do
    # call your procedure/other scripts here below
    echo "$i"
done
Run Code Online (Sandbox Code Playgroud)


Mar*_*cki 7

#/bin/bash   
TESTSTR="abc,def,ghij"

for i in $(echo $TESTSTR | tr ',' '\n')
do
echo $i
done
Run Code Online (Sandbox Code Playgroud)

我更喜欢使用 tr 而不是 sed,因为 sed 在某些情况下会遇到特殊字符(如 \r \n)的问题。

其他解决方案是将 IFS 设置为某个分隔符