[英]How to capture “*” as argument to bash function and use in a comparison
[英]How to optimize this bash function?
我已經制作了一個bash函數,該函數可以將大於特定大小的圖像文件分開,但是我大約有20000個文件,這花費了太多時間,並且根本沒有占用太多CPU,所以我想知道是否有可能在沒有真正復雜的多重處理的情況下對其進行一點優化(我不介意多重處理,但我不想為如此簡單的任務編寫20行代碼)
這是我的代碼:
getpics() {
dir="larger than $1x$2"
mkdir "$dir"
for f in `ls *`; do
a=`file "$f" | grep -Po ", \K[\d]*x[\d]*"`
x=`grep -Po "\d*(?=x)" <<< "$a"`
y=`grep -Po "x\K\d*" <<< "$a"`
echo "$a _______________________ $x, $y"
if [ $x -gt $1 ] && [ $y -gt $2 ] ; then
mv "$f" "$dir/$f"
fi
done
}
您可以嘗試盡可能避免調用外部工具,而使用bash
內置函數。
例如,要替換所有grep
,可以使用bash
ERE (在Bash 4+中有效):
re='^.* ([0-9]+)x([0-9]+),.*$'
for f in *; do
desc=$(file "$f")
if [[ $desc =~ $re ]]; then
x=${BASH_REMATCH[1]}
y=${BASH_REMATCH[2]}
# ... check size & move
fi
done
ls
輸出 grep
調用(感謝下面的評論和@randomir的回答) 重構腳本:
re=', ([0-9]+)x([0-9]+)'
getpics() {
dir="larger than $1x$2"
mkdir "$dir"
for f in *; do
if [[ $(file "$f") =~ $re ]]; then
x=${BASH_REMATCH[1]}
y=${BASH_REMATCH[2]}
echo "$a _______________________ $x, $y"
(( x > $1 && y > $2 )) && mv "$f" "$dir/$f"
fi
done
}
首先讓我們做一些基准測試:
我們從if開始:
$ time for i in `seq 1 100000`; do if [ 2 -gt 1 ] && [ 3 -gt 2 ]; then a=1; fi; done
real 0m0.694s
user 0m0.693s
sys 0m0.003s
$ time for i in `seq 1 100000`; do if [[ 2 -gt 1 && 3 -gt 2 ]]; then a=1; fi; done
real 0m0.428s
user 0m0.424s
sys 0m0.006s
$ time for i in `seq 1 100000`; do if (( 2 > 1 && 3 > 2 )); then a=1; fi; done
real 0m0.366s
user 0m0.364s
sys 0m0.003s
$ time for i in `seq 1 100000`; do (( 2 > 1 && 3 > 2 )) && a=1; done
real 0m0.355s
user 0m0.352s
sys 0m0.005s
現在讓我們看看ls
$ time for i in `ls *`; do a=1; done
real 0m0.280s
user 0m0.249s
sys 0m0.036s
$ time for i in *; do a=1; done
real 0m0.128s
user 0m0.128s
sys 0m0.000s
現在有些人可能會懷疑
desc=$(file "$f")
if [[ $desc =~ $re ]]; then
會不同於
if [[ $(file "$f") =~ $re ]]; then
但是結果沒有區別。 我也測試了很多次,但是每次都比另一個隨機地快。 但我沒有將其結果放在這里,因為我認為它沒有用。
再次,您可能想知道之間是否存在差異
^.* ([0-9]+)x([0-9]+),.*$
和([0-9]+)x([0-9]+),
但是我測試了它,沒有。 但是根據regex101 ,最好的正則表達式(保留分組)是:
.*, ([0-9]+)x([0-9]*) : 33 steps.
, ([0-9]+)x([0-9]+) : 34 steps.
^.* ([0-9]+)x([0-9]+),.*$ : 38 steps.
現在讓我們比較獲取x
和y
不同方法:
$ time (files=( * ); for f in "${files[@]:0:1000}"; do IFS=, a=(`file $f`);IFS=x b=(${a[8]});done;)
real 0m5.580s
user 0m1.147s
sys 0m4.498s
$ time (files=( * ); for f in "${files[@]:0:1000}"; do if [[ $(file "$f") =~ $re ]]; then x=${BASH_REMATCH[1]}; y=${BASH_REMATCH[2]}; fi; done)
real 0m5.817s
user 0m1.234s
sys 0m4.619s
$ time (files=( * ); for f in "${files[@]:0:1000}"; do a=(`convert $f -print "%w %h\n" /dev/null`);done;)
real 0m10.356s
user 0m3.624s
sys 0m6.793s
$ time (files=( * ); for f in "${files[@]:0:1000}"; do a=$(file "$f" | grep -Po ", \K\d+x\d+"); IFS=x read x y <<<"$a"; done;)
real 0m12.645s
user 0m2.235s
sys 0m13.914s
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.