2013-06-04 66 views
0

我有一個bash腳本需要2個參數 - 一個字符和整數。我想打印在aplhabet字符開始與整數的長度是字符(模字母)Bash - 使用ASCII很慢

#!/bin/bash 

[[ $# != 2 ]] && echo Exactly 2 argument needed && exit 1 
[[ "$1" =~ ^[a-zA-Z]$ ]] || { echo Enter only one char; exit 2; } 
[[ "$2" =~ ^[0-9]+$ ]] || { echo Enter integer; exit 3; } 

letter="$1" 
cnt="$2" 
letter=`printf "%d" \'$letter`; 
z=`printf "%d" \'z` 
a=`printf "%d" \'a` 
[[ "$1" =~ ^[[:upper:]]$ ]] && { ((letter+=32)); }   # make lower 

while [[ "$cnt" -gt 0 ]]; do 

    printf \\$(printf "%03o" "$letter") 
    ((letter++)) 
    [[ "$letter" -gt $z ]] && letter=$a      # alphabet modulo 
    ((cnt--)) 
done 
echo "" 

這個腳本工作完全正常,但它的速度太慢。我必須調用2×n(int的值)printf程序。

我的問題是如果有像enable printf工作解決方案來提高printf執行的速度或某些解決方案根本不使用printf。

我需要使用bash,我只想知道如何處理ASCII最快的方式。我在cygwin atm上編寫腳本,所以可能會有一些速度與它失敗有關。

這個腳本只是一個問題的例子,我不想要一些「增加stdout flush buffer size」的解決方案。謝謝:)

+0

'bash'被設計用於其他程序,不批量數據處理膠合在一起。如果您想以最快的方式處理數據,請選擇其他語言。 – chepner

+0

@chepner是對的。在perl或python這樣的語言中(這在cygwin中也可用)會更快。 – Samveen

回答

2

在這裏你去:

#!/bin/bash 

[[ $# != 2 ]] && echo Exactly 2 argument needed && exit 1 
[[ "$1" =~ ^[a-zA-Z]$ ]] || { echo Enter only one char; exit 2; } 
[[ "$2" =~ ^[0-9]+$ ]] || { echo Enter integer; exit 3; } 

alpha=`echo {a..z}|sed 's/ //g'` 
letter="$1" 
cnt="$2" 
letter=$(expr `printf "%d - %d + 1" \'$letter \'a`;) 

[[ "$1" =~ ^[[:upper:]]$ ]] && { ((letter+=32)); }   # make lower 

echo -n `echo $alpha |tail -c +$letter |head -c $cnt` 
((cnt=cnt-26)) 
while [[ "$cnt" -gt 0 ]]; do 
    echo -n `echo $alpha |head -c $cnt` 
    ((cnt=cnt-26)) 
done 
echo "" 

此程序使用括號擴展,擴大a..z成字符的列表,然後顯示用的頭部和尾部此字符串尺寸裁剪。它可能會更加優化,但這對你來說是一種鍛鍊。

性能比較(<1>是有問題的代碼,<2>是代碼在這個答案):
*如<1>相比3啓動部分具有<2> 4級的命令。
* <2>與每個字符<1>中的1個命令相比,每26個字符運行4個命令(echo(x2),head,tail)。
* <2>每26個字符有一個算術運算,而<1>每個字符有2個算術運算。

[email protected]:/tmp$ time bash 1.sh a 1000 
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl 

real 0m2.065s 
user 0m0.244s 
sys  0m0.552s 
[email protected]:/tmp$ time bash 2.sh a 1000 
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl 

real 0m0.285s 
user 0m0.024s 
sys  0m0.060s 

進一步閱讀:man bash

+0

我喜歡這個想法。標記爲答案。 – bartimar