Loop through a comma-separated shell variable

2019-03-08 02:46发布

Suppose I have a Unix shell variable as below

variable=abc,def,ghij

I want to extract all the values (abc, def and ghij) using a for loop and pass each value into a procedure.

The script should allow extracting arbitrary number of comma-separated values from $variable.

7条回答
【Aperson】
2楼-- · 2019-03-08 03:21

If you set a different field separator, you can directly use a for loop:

IFS=","
for v in $variable
do
   # things with "$v" ...
done

You can also store the values in an array and then loop through it as indicated in How do I split a string on a delimiter in Bash?:

IFS=, read -ra values <<< "$variable"
for v in "${values[@]}"
do
   # things with "$v"
done

Test

$ variable="abc,def,ghij"
$ IFS=","
$ for v in $variable
> do
> echo "var is $v"
> done
var is abc
var is def
var is ghij

You can find a broader approach in this solution to How to iterate through a comma-separated list and execute a command for each entry.

Examples on the second approach:

$ 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 --
查看更多
smile是对你的礼貌
3楼-- · 2019-03-08 03:28

You can use the following script to dynamically traverse through your variable, no matter how many fields it has as long as it is only comma separated.

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

Instead of the echo "$i" call above, between the do and done inside the for loop, you can invoke your procedure proc "$i".


Update: The above snippet works if the value of variable does not contain spaces. If you have such a requirement, please use one of the solutions that can change IFS and then parse your variable.


Hope this helps.

查看更多
三岁会撩人
4楼-- · 2019-03-08 03:34

Try this one.

#/bin/bash   
testpid="abc,def,ghij" 
count=`echo $testpid | grep -o ',' | wc -l` # this is not a good way
count=`expr $count + 1` 
while [ $count -gt 0 ]  ; do
     echo $testpid | cut -d ',' -f $i
     count=`expr $count - 1 `
done
查看更多
走好不送
5楼-- · 2019-03-08 03:35
#/bin/bash   
TESTSTR="abc,def,ghij"

for i in $(echo $TESTSTR | tr ',' '\n')
do
echo $i
done

I prefer to use tr instead of sed, becouse sed have problems with special chars like \r \n in some cases.

other solution is to set IFS to certain separator

查看更多
爷的心禁止访问
6楼-- · 2019-03-08 03:36

Not messing with IFS
Not calling external command

variable=abc,def,ghij
for i in ${variable//,/ }
do
    # call your procedure/other scripts here below
    echo "$i"
done

Using bash string manipulation http://www.tldp.org/LDP/abs/html/string-manipulation.html

查看更多
叼着烟拽天下
7楼-- · 2019-03-08 03:37

Here is an alternative tr based solution that doesn't use echo, expressed as a one-liner.

for v in $(tr ',' '\n' <<< "$var") ; do something_with "$v" ; done

It feels tidier without echo but that is just my personal preference.

查看更多
登录 后发表回答