内部ループ条件は、外部ループ動作に依存します。

内部ループ条件は、外部ループ動作に依存します。

ループ条件が実行中の外部ループに依存するように内部ループをどのように設定できますか?

私の状況は私が探しているコードにとって重要ではないかもしれませんが、状況は次のとおりです。 URLが両方のパラメータに依存する変更URLで実行したいクローラがあります。最初は年、2番目はページ、ページの範囲は年によって異なります。

私が今まで試したことは次のとおりです。

#!/bin/bash

numbers2004={625..721}
numbers2005={723..823}

for year in 2004 2005
do
  for number in numbers$year
  do
    echo "$year $number"
  done
done

それは私に与えなければなりません

2004 625
2004 626
...
2004 720
2004 721
2005 723
2005 724
...
2005 822
2005 823

答え1

現在のbashバージョンを使用する:

#!/bin/bash

declare -A numbers    # declare associative array
printf -v numbers[2004] "%s " {625..721}
printf -v numbers[2005] "%s " {723..823}

for year in 2004 2005
do
  for number in ${numbers[$year]}
  do
    echo "$year $number"
  done
done

答え2

以下はCyrusの答えを変えたものです。パラメータ間接。しかしながら、リンクから分かるように、配列ベースのアプローチは間接的なアプローチを使用するよりも好ましい。評価する、できるだけ避けてください。

(出力を少し小さくするためにOPに提供されている数値の範囲を絞り込みました)。

#!/usr/bin/env bash

printf -v numbers2004 "%d " {625..635}
printf -v numbers2005 "%d " {723..733}

for year in 2004 2005
do
    numbers="numbers$year"
    for number in ${!numbers}
    do
        printf "%s %s\n" "$year" "$number"
    done
done

出力

2004 625
2004 626
2004 627
2004 628
2004 629
2004 630
2004 631
2004 632
2004 633
2004 634
2004 635
2005 723
2005 724
2005 725
2005 726
2005 727
2005 728
2005 729
2005 730
2005 731
2005 732
2005 733

答え3

変数を介して間接的にこれを達成することもできます。

#!/bin/bash

numbers2004="$(printf "%s " {625..721})"
numbers2005="$(printf "%s " {723..823})"

for year in 2004 2005
do
  for number in $(eval echo \$numbers$year)
  do
    echo "$year $number"
  done
done

答え4

evalやりたいことをしなければなりません...

numbers2004={625..721}
numbers2005={723..823}

for year in 2004 2005
do
  eval 'eval "for number in '"\$numbers$year"'
  do
    echo \"\$year \$number\"
  done"'
done

...印刷...

2004 625
...
2004 721
2005 723
...
2005 823

しかし、これはひどい方法です。引用が悪夢であるだけでなく、おそらく最も重要なのは、シェルがすべてのことを行うからです。二重。まず、すべての{brace..expanded}反復可能オブジェクトを作成する必要があります。今後その後、それぞれを繰り返します。

代わりに、おそらく:

y=4 n=623 c=721
while  [ "$((y+=$c<(c+=102*(c<(n+=1<<(c==n))))))" -lt 6  ] 
do    echo "200$y $n"
done

busybox ash... ksh93、、、、、、、、dashおよびの最新バージョンでもyash同じbash内容を印刷します。zshmkshposh

ほとんどの算術式と同様に、必要に応じて内容の一部のみを評価して、算術式のパフォーマンスをわずかに向上させることができます。

y=4 n=623 c=721
while [ "$((c<(n+=1)?(y+=(n+=1)<(c+=102)):y))" -lt 6 ] 
do echo "200$y $n"
done

...上記のすべてのシェルで同じように動作します。ただし、...常に三項門のすべての側面を評価しているbusyboxように見えるので、期待どおりに繰り返すことはできません。busyboxif expr ? true : false

関連情報