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

bashC ライクな構文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 億個の数値を生成し (バーは 2、3 個)、数字のリストだけを保持するために 800 MiB 程度のメモリが必要です (おそらく過小評価です。各数値は個別のメモリ割り当てに保持される可能性があり、これは 8 バイトを意味する可能性があります)。割り当てられたブロックのポインターと 16 バイト。これにより、記憶域の見積もりが 3 倍になります)。

以下を使用することで、物事を劇的に改善できます。

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 それでも=>seqpipe| を使用したい場合は、 a を使用してループを分離します
このソリューションは移植性が高く、他のシェルで使用できます。
メモリ プリントは引き続き削減されますが、このスクリプトでは 2 つのスレッドを処理する必要があります。

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 に答える