以下は、ボックス内に存在するすべての DSF を読み取るためのシェル スクリプトです。しかし、行にスペースがあるため、それらを別の行に表示しています。理解していない人のためioscan -m dsf
に、に置き換えてくださいls -ltr
。出力は、権限と名前が別の行に表示されるようになっていますが、同じ行に表示したいです。
#!/usr/bin/ksh
for a in `ioscan -m dsf`
do
echo $a
done
for
ループは「行」をループするようには設計されていません。代わりに、「単語」または「フィールド」をループします。
行をループする慣用的な方法は、while
ループを。と組み合わせて使用することread
です。
ioscan -m dsf | while read -r line
do
printf '%s\n' "$line"
done
パイプがあるため、whileループはサブシェルにあることに注意してください。これにより、可変スコープとの混乱が生じる可能性があります。bashでは、プロセス置換を使用してこれを回避できます。
while read -r line
do
printf '%s\n' "$line"
done < <(ioscan -m dsf)
http://mywiki.wooledge.org/BashFAQ/024も参照してください
$IFS
forループは、 (内部フィールド区切り文字)変数の文字を区切り文字として使用して、値を分割してループします。通常$IFS
、スペース、タブ、および改行が含まれます。つまり、for
ループは行ではなく「単語」をループします。
forループを使用して行をループすることを主張する場合は、の値を$IFS
改行のみに変更する必要があります。ただし、これを行う場合は、の古い値を保存し$IFS
、ループの後でそれを復元する必要があります。これは、他の多くのものもに依存しているため$IFS
です。
OLDIFS="$IFS"
IFS=$'\n' # bash specific
for line in $(ioscan -m dsf)
do
printf '%s\n' "$line"
done
IFS="$OLDIFS"
ANSI-C引用符( )がないPOSIXシェルでは、次の$'\n'
ように実行できます。
IFS='
'
つまり、引用符の間に実際の改行を入れます。
または、サブシェルを使用して、次の変更を含めることができます$IFS
。
(
# changes to variables in the subshell stay in the subshell
IFS=$'\n'
for line in $(ioscan -m dsf)
do
printf '%s\n' "$line"
done
)
# $IFS is not changed outside of the subshell
ただし、ループ内のコマンド自体がの適切な設定に依存している可能性があることに注意してください$IFS
。次に、コマンドを実行する前に復元し$IFS
、次のループなどの前に再設定する必要があります。をいじることはお勧めしません$IFS
。あまりにも多くのコマンドは、のいくつかの正しい値に依存しており、$IFS
それを変更することは、あいまいなバグハンティングの終わりのない悪夢です。
参照:
これを基本的に使用する必要がありIFS=$'\n'
、grep -x
代わりgrep
に、like 演算子ではなく equal to 演算子のように機能します。