Bash の for ループで使用する文字列を分割したいと考えています。たとえば、私はこの文字列を持っています
hello,my,name,is,mindia
そして、それを個々の単語に分割して、各単語をループできるようにします。誰か助けてくれませんか?
非常に簡単な方法は、配列への単語分割を使用することです。
s="hello,my,name,is,mindia"
入力フィールドセパレーターを ,: に設定します。
IFS=,
次に、文字列を配列に分割します。
a=( $s )
結果:
for word in "${a[@]}"; do echo "- [$word]"; done
純粋なbashを使用し、noを使用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
もう 1 つの良い点は、IFS
がグローバルに設定されていないことです。コマンドに対してのみ設定されます。後で!read
をグローバルに設定したことを忘れても、驚くことはありません。IFS
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
パターン置換を使用できます。
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,}"