Условия внутреннего контура должны зависеть от хода внешнего цикла

Как я могу построить внутренний цикл таким образом, чтобы условие цикла зависело от запуска внешнего цикла?

Моя ситуация, вероятно, не имеет значения для кода, который я ищу, но вот он: у меня есть искатель, который я хочу запустить при изменении URL-адресов, где URL-адрес зависит от двух параметров. Первый – это год, а второй – страницы, а диапазон страниц варьируется от года к году.

  • Использовать сохраненный ввод для скриптов
  • Как исправить bash или auto run / bin / bash в SSH login
  • Удаление номеров строк с выхода `od`
  • Может ли любая оболочка использовать интерактивный поиск на уровне аргументов?
  • Как написать скрипт bash для настройки моих дисплеев, когда HDMI подключен или отсоединен
  • Как преобразовать специальный шестнадцатеричный символ из html-страницы в bash?
  • Вот что я пробовал до сих пор

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

  • Вставьте пустую строку между запросами командной строки
  • Как передать вывод скрипта команде ls без разделения данных?
  • Выделение / исключение / расширение в "команде в переменной"
  • ошибка: у Macro% есть незаконное имя (% define)
  • вызов команды из скрипта и сохранение стиля
  • Как подавить отображение предыдущих заданий?
  • 4 Solutions collect form web for “Условия внутреннего контура должны зависеть от хода внешнего цикла”

    С текущей версией 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 

    Вот вариант ответа Кира, который использует косвенное использование параметра . Однако, как говорится в ссылке, массивные подходы предпочтительнее использования косвенности, поскольку такая косвенность является близким родственником eval , чего следует избегать, когда это возможно.

    (Я уменьшил диапазоны чисел от значений, указанных в 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 

    Вы также можете достичь этого с переменной косвенностью:

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

    Вам нужно 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 if expr ? true : false тернарное утверждение и поэтому не выполняет итерацию, как ожидалось.

    Linux и Unix - лучшая ОС в мире.