2015-02-03 2 views
0

A стандартной петли отлично работает для меняBash проблема петли сценария при замене постоянной с помощью переменной

for i in {1..3} 
do 
    echo "$i" 
done 

Выход

1 
2 
3 

Но если заменить константу на переменную (после объявления его, конечно,) это не так.

n=3 
for i in {1..$n} 
do 
    echo "$i" 
done 

Выход

{1..3} 

Извинения, если это глупый вопрос. Я попытался найти SO и Google, но не повезло.

Развейте вопрос:

declare -a nOptions={3,4}; 
for i1 in $(seq 1 ${nOptions[0]}); 
do 
    for i2 in $(seq 1 ${nOptions[1]}); 
    do 
    echo "$i1$i2" 
    done 
done 

Это дает

OUTPUT
11 
21 
31 
41 

и не

11 
12 
13 
14 
21 
22 
23 
24 
31 
32 
33 
34 

, как ожидалось.

+0

Это, кстати, вопрос. См. Http://mywiki.wooledge.org/BashPitfalls#for_i_in_.7B1...24n.7D –

+0

Ваши 'nOptions' не являются допустимым объявлением массива. Может быть, вы имеете в виду 'nOptions = (3 4)'? –

+0

Вам нужно объявить 'nOptions' как массив, что означает скобки в правой части. Вы можете использовать фигурные скобки внутри круглых скобок, если вы хотите сделать последовательность: 'nOptions = ({3..5})' –

ответ

2

Расширение Curly-brace происходит перед расширением параметра (или любым другим расширением). Литерал $variable не похож на другой конец диапазона, поэтому он не вызывает расширение диапазона.

Чтобы использовать переменный счетчик, просто использовать цикл подсчета:

for ((i=1; i<=$n; ++i)); do 

done 

В большинстве современных систем (по крайней мере, Linux и OS X), вы можете использовать команду seq, хотя это не является часть стандарта POSIX ни встроенная в Bash себя:

for i in $(seq 1 $n); do 

done 

Если вы по какой-то причине мертвой набор на использовании Curlies, вы можете добавить eval, но это будет сделать решение хрупким и опасным.

+0

спасибо! последующие вопросы (это был мой первоначальный вопрос, прежде чем я его отредактировал). при применении этого для вложенного цикла он работает только для самой внешней переменной, но не для других :(любые предложения? –

+0

Boo, hiss re: 'seq' - не часть стандарта POSIX, а также не встроенный bash, поэтому no что он будет присутствовать в любой системе, даже если эта система имеет bash. Гораздо лучше использовать цикл C-стиля - или, если вы хотите совместимость с POSIX, i = 0, а ["$ i" -lt "$ n"]; do ...; i = $ ((i + 1)); –

Смежные вопросы