0

我有一个带有 2 个参数的 bash 脚本——一个字符和一个整数。我想在 aplhabet 中打印以该整数长度的字符开头的字符(以字母表为模)

#!/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 ""  

这个脚本工作得很好,但是太慢了。我必须调用 printf 程序的 2x n(int 值)。

我的问题是,是否有诸如enable printf提高 printf 执行速度的工作解决方案或根本不使用 printf 的解决方案。

我需要使用 bash,我只想知道如何以最快的方式处理 ASCII。我在 cygwin atm 上编写脚本,因此可能会出现一些与此相关的速度故障。

这个脚本只是一个问题的说明,我不想要一些“增加标准输出刷新缓冲区大小”的解决方案。谢谢 :)

4

1 回答 1

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>的代码,是这个答案中的代码):
* 启动部分有 4 个命令 in<2>而 3 in <1>
*<2>每 26 个字符运行 4 个命令(echo (x2)、head、tail),而<1>.
*<2>每 26 个字符有一个算术运算,而每个字符<1>有 2 个算术运算。

samveen@precise:/tmp$ time bash 1.sh a 1000
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl

real    0m2.065s
user    0m0.244s
sys     0m0.552s
samveen@precise:/tmp$ time bash 2.sh a 1000
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl

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

进一步阅读:man bash

于 2013-06-04T13:18:18.530 回答