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

Хижина не была предназначена, чтобы быть настолько гибкой. Могут быть некоторые случаи, где наличие второго параметра работает, я думаю, что FreeBSD является одним из них.

таращите глаза и большинство утилит, которые идут с ОС, как, ожидают, будут в /usr/bin/.

В более старые дни UNIX было распространено иметь /usr/ смонтированный по NFS или некоторым менее дорогим медиа для оставления свободного места локального диска и стоимости на рабочую станцию. /bin/ как предполагалось, имел все, должен был загрузиться в однопользовательском режиме. С тех пор /usr/ не был смонтирован на надежные медиа, /bin/ включенный достаточно утилит для создания этого достаточно дружественным для общего администрирования и поиска и устранения неисправностей.

Это было наследовано в Linux первоначально, но поскольку дисковое пространство больше не является проблемой и в большинстве случаев /usr/ находится в корневой файловой системе, современная тенденция состоит в том, чтобы переместить все в /usr/bin (по крайней мере, в мире Linux). Таким образом, большинство утилит, установленных дистрибутивом, как ожидают, будет найдено там. Даже самые основные утилиты, как cp, rm, ls и т.д. (хорошо, еще).

Относительно выбора хижины. Традиционно, это - что-то, администраторы или пользователи должны отредактировать согласно их среде. Для всего разработчик знает в системах других людей, интерпретатор мог быть где угодно в файловой системе (например, /usr/local/bin, /opt/gawk-4.0.1/bin). Правильно упакованные сценарии (об/мин, deb и т.д.) идут с любым зависимость от пакета дистрибутива (т.е. интерпретатор имеет известное расположение), или сценарий конфигурации, который устанавливает надлежащий hashbang во время установки.

3
17.12.2014, 02:40
4 ответа

С текущей версией 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
27.01.2020, 21:23

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

#!/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
0
27.01.2020, 21:23

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

0
27.01.2020, 21:23

Вот вариант ответа Cyrus Это использует нарушение параметра . Однако, поскольку ссылка считается, что подходы на основе массива должны быть предпочтительными в отношении использования косвения, поскольку такое косвествие является близким двоюродным братом 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
1
27.01.2020, 21:23

Теги

Похожие вопросы