2012-03-15 17 views
1

私はここにこのシェルスクリプトを持っています。しかし、最後に変数を表示しようとすると、小さな、中、大のいずれかに付加された$ファイル変数が標準出力に表示されません。シェルがここで何をしているのですか?それを修正するために何ができますか?ここには何が起こっていますか?シェルプログラミング

#!/bin/sh 

# sorts txt files into small, medium and large 
# depending on number of lines 
# small <= 10 
# medium <= 100 
# large > 100 

small="Small Files:" 
medium="Medium Files:" 
large="Large Files:" 

for txtFile in *.txt 
do 
    wc -l $txtFile 
done | 
while read lineCount file 
do 
    if [ $lineCount -lt 10 ] 
    then 
     small="$small $file" 

    elif [ $lineCount -lt 100 ] 
    then 
     medium="$medium $file" 
    else 
     large="$large $file" 
    fi 
done 
echo "$small" 
echo "$medium" 
echo "$large" 

答えて

3

あなたがパイプラインを使用すると、パイプラインのステージが別々のプロセスやメイン処理に戻って伝播しない割り当てられている変数として実行されます。

small="Small Files:" 
medium="Medium Files:" 
large="Large Files:" 

for txtFile in *.txt 
do 
    wc -l $txtFile 
done | (
    while read lineCount file 
    do 
    if [ $lineCount -lt 10 ] 
    then 
     small="$small $file" 
    elif [ $lineCount -lt 100 ] 
    then 
     medium="$medium $file" 
    else 
     large="$large $file" 
    fi 
    done 
    echo "$small" 
    echo "$medium" 
    echo "$large" 
) 

括弧は、whileループとエコー文は、単一のプロセスにグループ化させ、その変数の値が保存されている:あなたは、代わりにこのようにそれを行うことができます。あなたは、単純な例では、この効果を見ることができます

:可読性が

x=5;echo | (x=6;echo $x) 

が、あなたはまた、プロセス置換を使用することができます6.

1

が印刷されます一方

x=5;echo | x=6;echo $x 

は、5を印刷します幾分苦しむ:

while read lineCount file; do 
    if [ $lineCount -lt 10 ]; then 
    small="$small $file" 
    elif [ $lineCount -lt 100 ]; then 
    medium="$medium $file" 
    else 
    large="$large $file" 
    fi 
done < <(wc -l *txt) 

これはパイプラインを削除し、whileループが現在のシェルで実行されるために機能します。

+0

良い解決策ですが、これは役割を逆転させることに注意してください。 'wc'はまだサブシェルで実行されています。 – l0b0

+0

ここで問題となるのは、OPが '#!/ bin/sh'を使用しており、プロセス置換がベースラインのPOSIX shでは利用できないということだけです。 –

関連する問題