どのように動作しますか? forループは変数の結果を削除します。

どのように動作しますか? forループは変数の結果を削除します。

本から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"

または、ファイル名をに渡すのではなく、ファイルをwcstdinにリダイレクトしてファイル名を出力しません。wcwc

$ wc -c foo.txt
8 foo.txt
$ wc -c < foo.txt
8

おすすめ記事