我只是在寻找一种简单的方法来分配一个数字(或提供其他数学功能)。假设我有以下命令:
find . -name '*.mp4' | wc -l
如何将WC -L的结果除以3?
我见过的示例不处理重新定向/in。
使用 bc
:
$ bc -l <<< "scale=2;$(find . -name '*.mp4' | wc -l)/3"
2.33
相反,bash壳仅执行整数算术。
尴尬也非常强大:
$ find . -name '*.mp4' | wc -l | awk '{print $1/3}'
2.33333
如果使用awk
:
wc
$ find . -name '*.mp4' | awk 'END {print NR/3}'
2.33333
编辑2018-02-22:添加 shell connector
有多种方式:
取决于所需的精度和要完成的计算数!参见 shell connector
进一步!
使用bc
(二进制计算器)
find . -type f -name '*.mp4' -printf \n | wc -l | xargs printf "%d/3n" | 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
使用bash Interger内置数学处理器
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
纯bash
有了最近的64bits 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
包含两个数字圆形的浮动值。
nota :使用globstar
和**
!
引入 shell connector
如果您打算进行大量钙调,需要高精度并使用bash,则可以使用长期运行bc
sub Process :
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
(我会让您Google for answer to the ultimate question of life, the universe, and everything
;)
...并打印13线结果,以减少输出:
printf -v form "%s" "%5.3f "{,}{,}{,,};form+="%5.3fn";
按常规方式
testBc(){
for ((i=1; i<157; i++)) ;do
echo $(bc -l <<<"$i/42");
done
}
使用长期运行bc
sub Process :
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
哇!十秒钟在我的Raspberry-pi上!
然后:
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
小于一个秒 !!
希望结果是相同的,但是执行时间大不相同!
我的shell connector
我已经发布了一个连接器函数:github.com上的连接器式键 和我自己网站上的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"
此方法将正确处理包含新线的文件名的奇异EDGECase。