49

以下は、ボックス内に存在するすべての DSF を読み取るためのシェル スクリプトです。しかし、行にスペースがあるため、それらを別の行に表示しています。理解していない人のためioscan -m dsfに、に置き換えてくださいls -ltr。出力は、権限と名前が別の行に表示されるようになっていますが、同じ行に表示したいです。

#!/usr/bin/ksh

for a in `ioscan -m dsf`
do
 echo  $a
done
4

3 に答える 3

65

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も参照してください


$IFSforループは、 (内部フィールド区切り文字)変数の文字を区切り文字として使用して、値を分割してループします。通常$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それを変更することは、あいまいなバグハンティングの終わりのない悪夢です。

参照:

于 2012-05-25T10:04:25.207 に答える
-1

これを基本的に使用する必要がありIFS=$'\n'grep -x代わりgrepに、like 演算子ではなく equal to 演算子のように機能します。

于 2020-05-10T20:01:32.263 に答える