web-dev-qa-db-ja.com

コンマ区切りのシェル変数をループする

以下のようなUnixシェル変数があるとします

variable=abc,def,ghij

Forループを使用してすべての値(abcdef、およびghij)を抽出し、各値をプロシージャーに渡します。

スクリプトは、$variableから任意の数のコンマ区切り値を抽出できるようにする必要があります。

64
Ramanathan K

次のスクリプトを使用して、コンマだけで区切られている限り、フィールドの数に関係なく、変数を動的に走査できます。

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

上記のecho "$i"呼び出しの代わりに、forループ内のdodoneの間で、プロシージャproc "$i"を呼び出すことができます。


更新:上記のスニペットは、変数の値にスペースが含まれていない場合に機能します。そのような要件がある場合は、IFSを変更できるソリューションの1つを使用してから、変数を解析してください。


お役に立てれば。

77
anacron

IFSをいじらない
外部コマンドを呼び出さない

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

Bash文字列操作の使用 http://www.tldp.org/LDP/abs/html/string-manipulation.html

97
neric

別のフィールド区切り文字を設定する場合、forループを直接使用できます。

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

また、値を配列に格納してから Bashの区切り文字で文字列を分割するにはどうすればよいですか

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

テスト

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

このソリューションでは、 コンマ区切りリストを反復処理して、各エントリに対してコマンドを実行する方法 のより広範なアプローチを見つけることができます。

2番目のアプローチの例:

$ 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 --
39
fedorqui
#/bin/bash   
TESTSTR="abc,def,ghij"

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

私はsedの代わりにtrを使用することを好みます。なぜなら、sedは\ r\nのような特別な文字に問題がある場合があるからです。

他の解決策は、IFSを特定のセパレータに設定することです

4
Marek Lisiecki

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
0
user3071170

これを試してください。

#/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
0
Karthikeyan.R.S

これは、エコーを使用しないtrベースの代替ソリューションで、1ライナーとして表されています。

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

エコーのないきれいな感じですが、それは私の個人的な好みです。

0
6EQUJ5