0

在 bash 中,我需要运行一个从 i=1 循环到 i=99999999 的脚本,但它总是内存不足。有什么解决方法吗?还是 i 有最大值?

first=1
last=99999999
randomString="CXCXQOOPSOIS"

for val in $( seq $first $last )
do
  padVal=$( printf "%010d\n" $val )
  hash=$( echo -n $randomString$padVal | md5sum )
  if [[ "$hash" =~ ^000000) ]]; then
    echo "Number: $val"  >> log_000000
    echo "$val added to log - please check."
  fi
done
4

3 回答 3

5

bash提供类 C 语法for循环:

first=1
last=99999999
randomString="CXCXQOOPSOIS"

for ((val=$first; val<$last; val++))
do
  padVal=$( printf "%010d\n" $val )
  hash=$( echo -n $randomString$padVal | md5sum )
  if [[ "$hash" =~ ^000000) ]]; then
    echo "Number: $val"  >> log_000000
    echo "$val added to log - please check."
  fi
done
于 2012-01-09T16:23:35.883 回答
1

您的seq命令生成 1 亿个数字(除了一对),并且需要 800 MiB 左右的内存来保存数字列表(可能低估了;每个数字可能保存在单独的内存分配中,这可能意味着 8 个字节分配块的指针和 16 个字节,这使存储空间估计值增加了三倍)。

您可以使用以下方法显着改进:

for millions in $(seq 0 99)
do
    for smallstuff in $(seq -f "%6.0f" 0 999999)
    do
        val="$millions$smallstuff"
        ...
    done
done

这大大减少了所需的内存量;唯一需要注意的问题是它测试了原始代码没有测试的 0。

于 2012-01-09T15:54:01.440 回答
1

如果您仍想使用seq => seq,请使用 a 来分隔和循环pipe|
此解决方案更便携,可以在其他 shell 上使用。
内存打印仍然减少,但此脚本需要处理两个线程。

first=1
last=99999999
randomString="CXCXQOOPSOIS"

seq $first $last |
while read val
do
  padVal=$( printf "%010d\n" $val )
  hash=$( echo -n $randomString$padVal | md5sum )
  if [[ "$hash" =~ ^000000) ]]; then
    echo "Number: $val"  >> log_000000
    echo "$val added to log - please check."
  fi
done
于 2012-01-09T16:30:27.787 回答