22

数値を除算する(または他の数学関数を提供する)簡単な方法を探しています。次のコマンドがあるとしましょう。

find . -name '*.mp4' | wc -l

wc -lの結果を取得して3で割るにはどうすればよいですか?

私が見た例は、リダイレクトされたアウト/インを扱っていません。

4

4 に答える 4

49

使用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
于 2012-11-01T17:13:32.927 に答える
10

編集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

多くの計算を行う予定で、高精度が必要で、長時間実行さ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>&-

小さなデモ、パイプを使用してbashで分割するための最良の方法について!

計算範囲{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
于 2012-11-01T17:12:10.680 に答える
5

find . -name '*.mp4' | wc -l | xargs -I{} expr {} / 2

パイプスルーする複数の出力がある場合に最適ですxargs{}式の用語のプレースホルダーとして使用します。

于 2016-09-02T14:36:42.110 に答える
1

bashのバージョンによっては、この単純なタスクを見つける必要さえありません。

shopt -s nullglob globstar
files=( **/*.mp4 )
dc -e "3 k ${#files[@]} 3 / p"

このメソッドは、改行を含むファイル名の奇妙なエッジケースを正しく処理します。

于 2012-11-01T18:47:41.770 に答える