循环使用逗号分隔的shell变量
假设我有一个unixshell变量,如下所示循环使用逗号分隔的shell变量,shell,loops,unix,for-loop,cut,Shell,Loops,Unix,For Loop,Cut,假设我有一个unixshell变量,如下所示 variable=abc,def,ghij 我想使用for循环提取所有值(abc、def和ghij),并将每个值传递到一个过程中 该脚本应允许从$variable提取任意数量的逗号分隔值。请尝试此脚本 #/bin/bash testpid="abc,def,ghij" count=`echo $testpid | grep -o ',' | wc -l` # this is not a good way count=`expr $count
variable=abc,def,ghij
我想使用for循环提取所有值(abc
、def
和ghij
),并将每个值传递到一个过程中
该脚本应允许从$variable
提取任意数量的逗号分隔值。请尝试此脚本
#/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
您可以使用下面的脚本动态遍历变量,不管它有多少个字段,只要它是逗号分隔的
variable=abc,def,ghij
for i in $(echo $variable | sed "s/,/ /g")
do
# call your procedure/other scripts here below
echo "$i"
done
在for循环内的do
和done
之间,您可以调用过程proc“$i”
,而不是上面的echo“$i”
调用
更新:如果变量的值不包含空格,则上述代码段有效。如果您有这样的要求,请使用可以更改
IFS
的解决方案之一,然后解析您的变量
希望这有帮助。如果设置了不同的字段分隔符,可以直接使用
for
循环:
IFS=","
for v in $variable
do
# things with "$v" ...
done
您还可以将值存储在数组中,然后按如下所示在其中循环:
您可以在这个解决方案中找到更广泛的方法来解决问题
关于第二种方法的例子:
$ 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 --
$IFS=,read-ra vals不干扰IFS
不调用外部命令
variable=abc,def,ghij
for i in ${variable//,/ }
do
# call your procedure/other scripts here below
echo "$i"
done
使用bash字符串操作
我更喜欢使用tr而不是sed,因为sed在某些情况下与特殊字符\r\n有关
另一种解决方案是将IFS设置为某个分隔符另一种不使用IFS但仍保留空格的解决方案:
$ var="a bc,def,ghij"
$ while read line; do echo line="$line"; done < <(echo "$var" | tr ',' '\n')
line=a bc
line=def
line=ghij
$var=“a bc、def、ghij”
$whilereadline;do echo line=“$line”;完成<这里有一个替代的基于tr的解决方案,不使用echo,表示为一行
for v in $(tr ',' '\n' <<< "$var") ; do something_with "$v" ; done
对于$(tr')中的v,''\n'这是我的纯bash解决方案,它不改变IFS,并且可以接受自定义正则表达式分隔符
loop_custom_delimited() {
local list=$1
local delimiter=$2
local item
if [[ $delimiter != ' ' ]]; then
list=$(echo $list | sed 's/ /'`echo -e "\010"`'/g' | sed -E "s/$delimiter/ /g")
fi
for item in $list; do
item=$(echo $item | sed 's/'`echo -e "\010"`'/ /g')
echo "$item"
done
}
通过迭代你到底想做什么?我想通过每个字段(比如abc)作为过程的参数。但如果我不确定变量testpid中的字段数量,该怎么办?此外,我需要将上述变量的每个字段作为参数传递给过程。我希望这样做,直到变量的长度变为零。(即,所有字段都应传递一次给过程进行处理)我不知道这个过程。从这个链接可以得到字段的计数。http://stackoverflow.com/questions/8629330/unix-count-of-columns-in-file
。之后,将for循环转换为while循环。您可以获得该循环。我猜这是从文件中计算字段。如果我需要计算变量中的字段,该怎么办(假设变量为testpid=abc,def,ghij)回显变量并将输出传输到awk。或者查看我更新的答案。可能有用。另请参阅:-)祝大家好运。是的!我也想到了这一点,只是它需要执行以下步骤:awhile
读入数组,另一个读取结果。当有人真正知道如何使用shell,而不是将一堆binutil组合在一起时,这让我很高兴。你必须将IFS
设置回之前的状态吗re?@fedorqui它做到了!这是我想循环使用的唯一变量,它使我的yaml文件更易于读取(而不是一个长的环境变量,它有一堆行)。如果$variable
包含空格,则这不起作用,例如variable=ab,c,d
=>打印4行(a | b | c | d),而不是3行(a | b | c | d)此外,它还添加了新的引号,如**“value
**。如果有任何正则表达式可以删除,请更新。好的方面是可以使用不同的分隔符嵌套多个循环。好的建议!避免与IFS
混淆的好提示!小警告-如果$i
中的任何值包含空格,它们将被拆分。”(这可能是它以逗号分隔而不是空格分隔的形式传递的原因)如果以前的函数更改了IFS设置,那么这不起作用…将其更改为:对于${variable/,/$IFS}do中的i;echo“$i”;done
我收到错误消息“Bad substitution”当我尝试这种方法时,它在bash中正常工作,但是zsh会吞噬空间。
$ var="a bc,def,ghij"
$ while read line; do echo line="$line"; done < <(echo "$var" | tr ',' '\n')
line=a bc
line=def
line=ghij
for v in $(tr ',' '\n' <<< "$var") ; do something_with "$v" ; done
loop_custom_delimited() {
local list=$1
local delimiter=$2
local item
if [[ $delimiter != ' ' ]]; then
list=$(echo $list | sed 's/ /'`echo -e "\010"`'/g' | sed -E "s/$delimiter/ /g")
fi
for item in $list; do
item=$(echo $item | sed 's/'`echo -e "\010"`'/ /g')
echo "$item"
done
}