Я ищу базовый цикл, например:
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
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 "[email protected]"' 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.
Мне обычно нравится использовать небольшой вариант для стандартного цикла. Я часто использую это для запуска команды на нескольких удаленных хостах. Я использую расширение bash brace для создания циклов, которые позволяют мне создавать нецифровые for-loops.
Пример:
Я хочу запустить команду uptime на frontend hosts 1-5 и backend hosts 1-3:
% for host in {frontend{1..5},backend{1..3}}.mycompany.com
do ssh $host "echo -n $host; uptime"
done
Я обычно запускаю это как однострочную команду с точками с запятой на концах строк вместо более читаемой версии выше. Ключевое использование использования заключается в том, что фигурные скобки позволяют вам указать несколько значений, которые нужно вставить в строку (например, pre {foo, bar} после результатов в prefoopost, prebarpost) и разрешить подсчет/последовательности с использованием двойных периодов (вы можете использовать a..z и т.д.). Однако синтаксис с двойным периодом является новой функцией bash 3.0; более ранние версии не поддержат это.
#! /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?
если вы перегружены только в bash, то "for ((...))" решение, представленное выше, является лучшим, но если вы хотите что-то совместимое с POSIX SH, которое будет работать на всех устройствах, вам придется используйте "expr" и "while", а потому, что "(())" или "seq" или "i = я + 1" не являются переносимыми между различными оболочками
Я использую вариации этого времени для обработки файлов...
для файлов в *.log; do echo "Делать вещи с помощью: $files"; echo "Сделайте больше вещей с помощью: $files"; сделано;
Если вы хотите обработать списки файлов, просмотрите опцию -execdir для файлов.