数値を除算する(または他の数学関数を提供する)簡単な方法を探しています。次のコマンドがあるとしましょう。
find . -name '*.mp4' | wc -l
wc -lの結果を取得して3で割るにはどうすればよいですか?
私が見た例は、リダイレクトされたアウト/インを扱っていません。
使用bc
:
$ bc -l <<< "scale=2;$(find . -name '*.mp4' | wc -l)/3"
2.33
対照的に、bashシェルは整数演算のみを実行します。
Awkも非常に強力です。
$ find . -name '*.mp4' | wc -l | awk '{print $1/3}'
2.33333
wc
使用する場合でも必要ありませんawk
:
$ find . -name '*.mp4' | awk 'END {print NR/3}'
2.33333
編集2018-02-22:追加shell connector
必要な精度と実行する計算の数に応じて!さらに参照してくださいshell connector
!
bc
(2進計算機)を使用するfind . -type f -name '*.mp4' -printf \\n | wc -l | xargs printf "%d/3\n" | bc -l
6243.33333333333333333333
また
echo $(find . -name '*.mp4' -printf \\n | wc -l)/3|bc -l
6243.33333333333333333333
またはbashを使用すると、結果は整数のみになります。
echo $(($(find . -name '*.mp4' -printf \\n| wc -l)/3))
6243
res=000$((($(find . -type f -name '*.mp4' -printf "1+")0)*1000/3))
printf -v res "%.2f" ${res:0:${#res}-3}.${res:${#res}-3}
echo $res
6243.33
最近の64ビットbashでは、@ glennjackmanの使用のアイデアを使用することもできますがglobstar
、疑似フローティングの計算は次の方法で実行できます。
shopt -s globstar
files=(**/*.mp4)
shopt -u globstar
res=$[${#files[*]}000/3]
printf -v res "%.2f" ${res:0:${#res}-3}.${res:${#res}-3}
echo $res
6243.33
フォークはなく$res
、2桁の丸められた浮動小数点値が含まれています。
注意:とを使用するときはシンボリックリンクに注意してください!globstar
**
shell connector
多くの計算を行う予定で、高精度が必要で、bashを使用する場合は、長時間実行さbc
れるサブプロセスを使用できます。
mkfifo /tmp/mybcfifo
exec 5> >(exec bc -l >/tmp/mybcfifo)
exec 6</tmp/mybcfifo
rm /tmp/mybcfifo
それから今:
echo >&5 '12/34'
read -u 6 result
echo $result
.35294117647058823529
このサブプロセスは開いたままで使用可能です。
ps --sid $(ps ho sid $$) fw
PID TTY STAT TIME COMMAND
18027 pts/9 Ss 0:00 bash
18258 pts/9 S 0:00 \_ bc -l
18789 pts/9 R+ 0:00 \_ ps --sid 18027 fw
コンピューティング$PI
:
echo >&5 '4*a(1)'
read -u 6 PI
echo $PI
3.14159265358979323844
サブプロセスを終了するには:
exec 6<&-
exec 5>&-
計算範囲{1..157} / 42
(私はあなたにグーグルさせますanswer to the ultimate question of life, the universe, and everything
;)
...出力を減らすために、13の結果を行ごとに出力します。
printf -v form "%s" "%5.3f "{,}{,}{,,};form+="%5.3f\n";
通常の方法で
testBc(){
for ((i=1; i<157; i++)) ;do
echo $(bc -l <<<"$i/42");
done
}
長時間実行さbc
れるサブプロセスを使用することにより:
testLongBc(){
mkfifo /tmp/mybcfifo;
exec 5> >(exec bc -l >/tmp/mybcfifo);
exec 6< /tmp/mybcfifo;
rm /tmp/mybcfifo;
for ((i=1; i<157; i++)) ;do
echo "$i/42" 1>&5;
read -u 6 result;
echo $result;
done;
exec 6>&-;
exec 5>&-
}
なしで見てみましょう:
time printf "$form" $(testBc)
0.024 0.048 0.071 0.095 0.119 0.143 0.167 0.190 0.214 0.238 0.262 0.286 0.310
0.333 0.357 0.381 0.405 0.429 0.452 0.476 0.500 0.524 0.548 0.571 0.595 0.619
0.643 0.667 0.690 0.714 0.738 0.762 0.786 0.810 0.833 0.857 0.881 0.905 0.929
0.952 0.976 1.000 1.024 1.048 1.071 1.095 1.119 1.143 1.167 1.190 1.214 1.238
1.262 1.286 1.310 1.333 1.357 1.381 1.405 1.429 1.452 1.476 1.500 1.524 1.548
1.571 1.595 1.619 1.643 1.667 1.690 1.714 1.738 1.762 1.786 1.810 1.833 1.857
1.881 1.905 1.929 1.952 1.976 2.000 2.024 2.048 2.071 2.095 2.119 2.143 2.167
2.190 2.214 2.238 2.262 2.286 2.310 2.333 2.357 2.381 2.405 2.429 2.452 2.476
2.500 2.524 2.548 2.571 2.595 2.619 2.643 2.667 2.690 2.714 2.738 2.762 2.786
2.810 2.833 2.857 2.881 2.905 2.929 2.952 2.976 3.000 3.024 3.048 3.071 3.095
3.119 3.143 3.167 3.190 3.214 3.238 3.262 3.286 3.310 3.333 3.357 3.381 3.405
3.429 3.452 3.476 3.500 3.524 3.548 3.571 3.595 3.619 3.643 3.667 3.690 3.714
real 0m10.113s
user 0m0.900s
sys 0m1.290s
わお!私のラズベリーパイで10秒!!
次に:_
time printf "$form" $(testLongBc)
0.024 0.048 0.071 0.095 0.119 0.143 0.167 0.190 0.214 0.238 0.262 0.286 0.310
0.333 0.357 0.381 0.405 0.429 0.452 0.476 0.500 0.524 0.548 0.571 0.595 0.619
0.643 0.667 0.690 0.714 0.738 0.762 0.786 0.810 0.833 0.857 0.881 0.905 0.929
0.952 0.976 1.000 1.024 1.048 1.071 1.095 1.119 1.143 1.167 1.190 1.214 1.238
1.262 1.286 1.310 1.333 1.357 1.381 1.405 1.429 1.452 1.476 1.500 1.524 1.548
1.571 1.595 1.619 1.643 1.667 1.690 1.714 1.738 1.762 1.786 1.810 1.833 1.857
1.881 1.905 1.929 1.952 1.976 2.000 2.024 2.048 2.071 2.095 2.119 2.143 2.167
2.190 2.214 2.238 2.262 2.286 2.310 2.333 2.357 2.381 2.405 2.429 2.452 2.476
2.500 2.524 2.548 2.571 2.595 2.619 2.643 2.667 2.690 2.714 2.738 2.762 2.786
2.810 2.833 2.857 2.881 2.905 2.929 2.952 2.976 3.000 3.024 3.048 3.071 3.095
3.119 3.143 3.167 3.190 3.214 3.238 3.262 3.286 3.310 3.333 3.357 3.381 3.405
3.429 3.452 3.476 3.500 3.524 3.548 3.571 3.595 3.619 3.643 3.667 3.690 3.714
real 0m0.670s
user 0m0.190s
sys 0m0.070s
1秒未満!!
うまくいけば、結果は同じですが、実行時間は大きく異なります。
shell connector
コネクタ関数を公開しました:GitHub.comのConnector-bash と自分のサイトのshell_connector.sh。
source shell_connector.sh
newConnector /usr/bin/bc -l 0 0
myBc 1764/42 result
echo $result
42.00000000000000000000
find . -name '*.mp4' | wc -l | xargs -I{} expr {} / 2
パイプスルーする複数の出力がある場合に最適ですxargs
。{}
式の用語のプレースホルダーとして使用します。
bashのバージョンによっては、この単純なタスクを見つける必要さえありません。
shopt -s nullglob globstar
files=( **/*.mp4 )
dc -e "3 k ${#files[@]} 3 / p"
このメソッドは、改行を含むファイル名の奇妙なエッジケースを正しく処理します。