コピーされた各ファイルのサイズを個別に印刷する代わりに、以下のコードからコピーされるファイルの合計サイズを印刷したいと思います。
#!/bin/bash
input_folder=/a/b/c
output_folder=/d/e/f
cd $input_folder
for i in *.tiff; do
size=$(wc -c < ${i})
cp -v ${i} $out | sleep 1 | echo -ne "$size%\033[0K\r"
done
bash
毎秒コピーされるファイルのサイズを印刷します。
たとえば、2番目にサイズを1
コピーして印刷します。次に、ファイルのフルサイズではなく、ファイルのサイズをコピーして印刷します。 2番目のステップでは、ファイルのフルサイズではなくファイルサイズをコピーして印刷します。file A
file A
2
file B
file B
A+B
3
file C
file C
A+B+C
どうすればいいですかbash
?
答え1
単一のサイズを要約するだけですecho
。
#!/bin/bash
input_folder=/a/b/c
output_folder=/d/e/f
cd $input_folder
size_sum=0
for i in *.tiff; do
size=$(wc -c < ${i})
size_sum=$((size_sum + size))
cp -v ${i} $out | sleep 1
done
echo ${size_sum}
答え2
size=$(wc -c < ${i})
これはファイルサイズを取得する非常に賢い方法ではありません。wc
そう走るのは読む必要なのは、ファイルシステムが既に知っていて知らせるサイズなので、実際には完全に不要なフルファイルです。
その後、どのような場合でもファイルを読み取るようにファイルをコピーして、この状況を軽減します。この間、適切なサイズのファイルがキャッシュに残る可能性があるため、読み取りは実際にディスクに到達しません。しかし、まだ寸法を読むことは合理的です。
GNUユーティリティを使用するとstat -c %s "$filename"
。stat
cp -v ${i} $out | sleep 1 | echo -ne "$size%\033[0K\r"
ここのパイプが変に見えますね。cp
(標準出力へ)出力は生成されません。少なくとも出力がない場合は生成されないので-i
パイプすることはありません。それでもsleep
何も読まないので、すべての出力がcp
無駄になります。sleep
との間にも同じことが起こりますecho
。これは基本的にパイプが通常使用されるものとは正反対ですが、すべてのコマンドが並列に実行され、シェルがすべてのコマンドが完了するのを待つため、パイプの実行には少なくとも1秒かかります。 、コピー速度に関係なく。
$(( .. ))
ファイルサイズを合計するには、シェルの算術拡張が必要な場合があります。そのため、さらに眠らなくても次のことができます。
dest=/path/to/destination
total=0
for file in *.tiff; do
size=$(stat -c %s "$file");
printf "current %d total %d\n" "$size" "$((total += size))"
cp -- "$file" "$dest"
done
答え3
スクリプトに算術演算を保存するには、ファイル接続サイズのみをインポートするだけです。
cat *.tiff | wc
UN*Xカーネルは、ユーザーと連携してファイルサイズのみを取得するのと同じくらい効率的です。
答え4
+=
変数が整数として宣言されたら、合計することができます。
$ declare -i size
$ size+=100; echo "$size"
100
$ size+=200; echo "$size"
300
あなたのスクリプト(変数拡張を正しく引用):
#!/bin/bash
input_folder=./a/b/c
output_folder=./d/e/f
declare -i size
for i in "$input_folder"/*; do
size+=$(wc -c < "${i}")
cp -v "${i}" "$output_folder" | sleep 1 | echo -ne "$size\033[0K\r"
done