本からbash/kshを学ぶとき。結果を知りたい運動を見つけました。
動作(デバッグ)を理解するために、bash -xを使用してこのスクリプトを実行すると、行変数が数値+ファイル名であることがわかりました。これは、wc -c [ファイル]の結果であるためです。ただし、forループがres変数を設定すると、何らかの形でファイル名が削除され、res = 23
(wc -cの数値結果)のみが表示されます。このようなことが起きているのがわかりますが、その理由をよく理解できませんか?私はforループ構造を理解すると思います。 for i in xxxの機能は何ですか。
練習スクリプトは次のとおりです。
if [ ! $# -eq 2 ] ;then
echo
echo "usage: $0 <location> <FileName>"
echo
exit 1
fi
TMPFILE=/tmp/count
line=$(find "$1" -name "$2" -type f -print | tee $TMPFILE | wc -l)
aant=$line
nr=0
som=0
while [ $nr -lt "$aant" ] ; do
nr=$(( nr +1 ))
bestand=$(head -$nr $TMPFILE | tail -1)
echo -n "$bestand"
line=$(wc -c "$bestand")
for woord in $line ; do
res=$woord
break
done
echo " $res"
som=$(( som + res ))
done
if [ "$aant" -eq 0 ] ; then
echo "No files found"
else
echo
echo "In totaal $aant files take $som bytes of space"
fi
rm $TMPFILE
exit 0
ベストアンサー1
for word in $line
、変数の内容はline
次のとおりです。単語に分ける次に、ファイル名グローバル変数を展開します(参照:これら 質問)。その後、ループは各結果値(または「単語」)に対して一度だけ実行されます。ただし、この場合、このbreak
ステートメントはループの実行を停止するため、ループには最大1回の反復があります。したがって、res
ループの最初の反復では、set値はそのまま残り、これはスペースで区切られた最初の単語を選択するのと同じ効果がありますline
。
これを書くより良い方法があります。たとえば、シェル拡張を使用してファイル名を削除できます。これにより、次のものが出力されます23
。
line='23 somefilename'
res="${line%% *}"
echo "$res"
または、ファイル名をに渡すのではなく、ファイルをwc
stdinにリダイレクトしてファイル名を出力しません。wc
wc
$ wc -c foo.txt
8 foo.txt
$ wc -c < foo.txt
8