Я ищу базовый цикл, например:
for(int i = 0; i < MAX; i++) {
doSomething(i);
}
но для bash.
Я ищу базовый цикл, например:
for(int i = 0; i < MAX; i++) {
doSomething(i);
}
но для bash.
Ответы:
С этого сайта :
for i in $(seq 1 10);
do
echo $i
done
for ((i = 0 ; i < max ; i++ )); do echo "$i"; done
ArrayLength=${#array[@]}
как мы используем ее здесь вместо max
?
Bash for
состоит из переменной (итератора) и списка слов, по которым итератор будет выполнять итерацию.
Итак, если у вас ограниченный список слов, просто введите их в следующем синтаксисе:
for w in word1 word2 word3
do
doSomething($w)
done
Вероятно, вы хотите перебрать некоторые числа, поэтому вы можете использовать seq
команду для создания списка чисел для вас: (например, от 1 до 100)
seq 1 100
и используйте его в цикле FOR:
for n in $(seq 1 100)
do
doSomething($n)
done
Обратите внимание на $(...)
синтаксис. Это поведение bash, оно позволяет передавать вывод одной команды (в нашем случае от seq
) к другой (команде for
)
Это действительно полезно, когда вам нужно перебрать все каталоги по некоторому пути, например:
for d in $(find $somepath -type d)
do
doSomething($d)
done
Возможности создания списков безграничны.
Bash 3.0+ может использовать этот синтаксис:
for i in {1..10} ; do ... ; done
.. что позволяет избежать создания внешней программы для расширения последовательности (например, seq 1 10
).
Конечно, это та же проблема, что и for(())
решение, привязка к bash и даже к конкретной версии (если это важно для вас).
Попробуйте bash
встроенную справку:
$ help for
for: for NAME [in WORDS ... ;] do COMMANDS; done
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not present, then `in "$@"' is
assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
Equivalent to
(( EXP1 ))
while (( EXP2 )); do
COMMANDS
(( EXP3 ))
done
EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is
omitted, it behaves as if it evaluates to 1.
#! /bin/bash
function do_something {
echo value=${1}
}
MAX=4
for (( i=0; i<MAX; i++ )) ; {
do_something ${i}
}
Вот пример, который также может работать в старых оболочках, но при этом эффективен для больших количеств:
Z=$(date) awk 'BEGIN { for ( i=0; i<4; i++ ) { print i,"hello",ENVIRON["Z"]; } }'
Но удачи в выполнении полезных вещей внутри awk
: Как использовать переменные оболочки в сценарии awk?
do
/ done
.
Обычно мне нравится использовать небольшой вариант стандартного цикла for. Я часто использую это для запуска команды на нескольких удаленных хостах. Я использую расширение скобок в bash для создания циклов for, которые позволяют мне создавать нечисловые циклы for.
Пример:
Я хочу запустить команду uptime на интерфейсных хостах 1-5 и внутренних хостах 1-3:
% for host in {frontend{1..5},backend{1..3}}.mycompany.com
do ssh $host "echo -n $host; uptime"
done
Я обычно запускаю это как однострочную команду с точками с запятой на концах строк вместо более удобочитаемой версии выше. Ключевое соображение использования заключается в том, что фигурные скобки позволяют вам указать несколько значений, которые будут вставлены в строку (например, результаты pre {foo, bar} post в prefoopost, prebarpost) и позволяют подсчет / последовательности с использованием двойных точек (вы можете использовать. .z и т. д.). Однако синтаксис с двойной точкой - это новая функция bash 3.0; более ранние версии не поддерживают это.
если вас интересует только bash, решение "for ((...))", представленное выше, является лучшим, но если вы хотите что-то совместимое с POSIX SH, которое будет работать на всех устройствах, вам придется использовать expr и "while", и это потому, что "(())" или "seq" или "i = i + 1" не переносимы между различными оболочками
Я все время использую его вариации для обработки файлов ...
для файлов в * .log; do echo "Что-нибудь делать с: $ files"; echo "Делайте еще что-нибудь с: $ files"; сделано;
Если вас интересует обработка списков файлов, загляните в изучите параметр -execdir для файлов .