8

ループ内でいくつかの文字列を連結し、結果を変数に代入する必要があります。

フォーマットされた文字列の例:

result=$(printf '| %-15s| %-25s| %-15s| %-15s| %-15s\n' $size $name $visits $inbound $outbound);

私の見解では、次のように機能するはずです。

result=''
while read somevar
do
    ...
    outbound=`cat "$www_path/$name/access.log"|grep \`date +"%d/%b/%Y"\`|awk '{ sum+=$11} END {print sum/1024/1024}'`
    result=$(printf '%s| %-15s| %-25s| %-15s| %-15s| %-15s\n' $result $size $name $visits $inbound $outbound);
    ...
done
echo $result

しかし、そうではありません:(

更新:

以下の完全なコードリスト:

www_path='/var/www';
result='';
cd /var/www/; ls -d */ | while read i ; do basename "$i" ; done
while read i;
do du -sh "$i"|
        while read size name
        do
                visits=`cat "$www_path/$name/access.log"|grep \`date +"%d/%b/%Y"\`|grep -v "internal dummy connection"|awk -F ' ' '{print $1}'  | sort | uniq | wc -l|tr '\n' '\t'|sed 's/$/\t/'`
                inbound=`cat "$www_path/$name/access.log"|grep \`date +"%d/%b/%Y"\`|grep -v "internal dummy connection"|awk '{ sum+=$10} END {print sum/1024/1024}'|tr '\n' '\t'|sed  's/$/\t\t/'`
                outbound=`cat "$www_path/$name/access.log"|grep \`date +"%d/%b/%Y"\`|grep -v "internal dummy connection"|awk '{ sum+=$11} END {print sum/1024/1024}'`;
                result=$(printf '%s| %-15s| %-25s| %-15s| %-15s| %-15s\n' "$result" "$size" "$name" "$visits" "$inbound" "$outbound")
        done
done
echo $result
4

2 に答える 2

14

プログラムまたは組み込み関数への単一の引数として使用する場合は、$result および空白やその他の特殊文字を含む可能性のあるその他のすべての変数を二重引用符で囲みます。

result=$(printf '%s| %-15s| %-25s| %-15s| %-15s| %-15s\n' "$result" "$size" "$name" "$visits" "$inbound" "$outbound")

printf の結果を変数に代入したいだけの場合(あなたがしたように)、次を使用することもできます

printf -v result '%s| %-15s| %-25s| %-15s| %-15s| %-15s\n' "$result" "$size" "$name" "$visits" "$inbound" "$outbound"

ところで: 文字列に追加するだけの += 代入演算子もあります (bash の man ページの PARAMETERS セクションを参照)。

完全なコード リストでは、「done」の後、2 番目の「while read i」の前にパイプ記号がありません。

そして電話すると

echo $result

'do du ...' の後にパイプ記号によって作成されたサブプロセスで printf が呼び出されるため、$result の内容は既に失われています。親プロセスは、サブプロセスの (環境) 変数にアクセスできません。

コードを次のように書き直します

result=""
for name in /var/www/* ; do 
    read size __ < <(du -sh "$name")
    name=${name##*/}
    #insert the other stuff here and add arguments to printf
    printf -v line '| %-15s| %-25s\n' "$size" "$name"
    result+=$line
done
echo "$result"

read < <(cmd)式は似ていますcmd | readが、前者は代わりにコマンドをサブプロセスに置き、読み取りはメインプロセスで実行します。このようにして、読み取りによって設定された変数は、後続のコマンドでも使用できます。

于 2013-04-13T21:28:11.023 に答える
3

あなたのコードは問題ないようです。追加するときに空白が含まれるため、行う必要があることの1つは、resultその展開を引用することです。

result=$(printf '...' "$result" "$size" "$name" ...)

他の変数を引用符で囲む必要はないかもしれませんが、通常は良い考えです。

ただし、引用に失敗し$resultても、完全に空白になることはありません。whileループにさらに多くのコードを投稿する必要がある場合があります。

于 2013-04-13T21:17:47.627 に答える