ループ条件が実行中の外部ループに依存するように内部ループをどのように設定できますか?
私の状況は私が探しているコードにとって重要ではないかもしれませんが、状況は次のとおりです。 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
内容を印刷します。zsh
mksh
posh
ほとんどの算術式と同様に、必要に応じて内容の一部のみを評価して、算術式のパフォーマンスをわずかに向上させることができます。
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
ように見えるので、期待どおりに繰り返すことはできません。busybox
if expr ? true : false