247
247
Bash. 変数の行を反復処理する
bash の変数やコマンドの出力から行を正しく反復処理するにはどうすればいいのでしょうか? IFS 変数を新しい行に設定するだけで、コマンドの出力では動作しますが、新しい行を含む変数を処理する場合には動作しません。しかし、最初の for ループは、1 行にすべての項目を印刷します。何かアイデアはありますか?
bash の変数やコマンドの出力から行を正しく反復処理するにはどうすればいいのでしょうか? IFS 変数を新しい行に設定するだけで、コマンドの出力では動作しますが、新しい行を含む変数を処理する場合には動作しません。しかし、最初の for ループは、1 行にすべての項目を印刷します。何かアイデアはありますか?
bash で文字列に改行を埋め込みたい場合は、$''
で囲みます:
$ list="One\ntwo\nthree\nfour"
$ echo "$list"
One\ntwo\nthree\nfour
$ list=$'One\ntwo\nthree\nfour'
$ echo "$list"
One
two
three
four
また、すでにそのような文字列が変数に入っている場合は、次のようにして行ごとに読むことができます:
while IFS= read -r line; do
echo "... $line ..."
done <<< "$list"
#!/bin/sh
items="
one two three four
hello world
this should work just fine
"
IFS='
'
count=0
for item in $items
do
count=$((count+1))
echo $count $item
done
ここでは for loop の変なやり方があります:
for item in ${list//\n/
}
do
echo "Item: $item"
done
もう少しわかりやすくて読みやすい方法は次のようになります:
cr='
'
for item in ${list//\n/$cr}
do
echo "Item: $item"
done
しかし、これは複雑すぎてスペースが必要になります:
for item in ${list//\n/ }
do
echo "Item: $item"
done
002 変数には改行が含まれていません。それは、$line
の後に`ここでは for loop の変なやり方があります:
for item in ${list//\n/
}
do
echo "Item: $item"
done
もう少しわかりやすくて読みやすい方法は次のようになります:
cr='
'
for item in ${list//\n/$cr}
do
echo "Item: $item"
done
しかし、これは複雑すぎてスペースが必要になります:
for item in ${list//\n/ }
do
echo "Item: $item"
done
002 変数には改行が含まれていません。それは、$line
の後にが続くインスタンスを含んでいます。あなたはと明確にそれを見ることができます:
$ cat t.sh
#! /bin/bash
list="One\ntwo\nthree\nfour"
echo $list | hexdump -C
$ ./t.sh
00000000 4f 6e 65 5c 6e 74 77 6f 5c 6e 74 68 72 65 65 5c |One\ntwo\nthree\|
00000010 6e 66 6f 75 72 0a |nfour.|
00000016
置換は、それがループのために動作するのに十分であるスペースでそれらを置き換えています:
$ cat t.sh
#! /bin/bash
list="One\ntwo\nthree\nfour"
echo ${list//\n/ } | hexdump -C
$ ./t.sh
00000000 4f 6e 65 20 74 77 6f 20 74 68 72 65 65 20 66 6f |One two three fo|
00000010 75 72 0a |ur.|
00000013
デモ:
$ cat t.sh
#! /bin/bash
list="One\ntwo\nthree\nfour"
echo ${list//\n/ } | hexdump -C
for item in ${list//\n/ } ; do
echo $item
done
$ ./t.sh
00000000 4f 6e 65 20 74 77 6f 20 74 68 72 65 65 20 66 6f |One two three fo|
00000010 75 72 0a |ur.|
00000013
One
two
three
four
また、最初に変数を配列に変換し、これを反復処理することもできます。
lines="abc
def
ghi"
declare -a theArray
while read -r line
do
theArray+=($line)
done <<< "$lines"
for line in "${theArray[@]}"
do
echo "$line"
#Do something complex here that would break your read loop
done
これは、IFS
をいじりたくない場合や、read
コマンドに問題がある場合にのみ有効です。