Вопрос
Я ищу базовый цикл, например:
for(int i = 0; i < MAX; i++) {
doSomething(i);
}
но для Баша.
Решение
От этот сайт:
for i in $(seq 1 10);
do
echo $i
done
Другие советы
for ((i = 0 ; i < max ; i++ )); do echo "$i"; done
Баш 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
Возможности создания списков безграничны.
Баш 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.
Обычно мне нравится использовать небольшой вариант стандартного цикла 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) и разрешает подсчет/последовательность с использованием двойных точек (вы можете использовать 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, которое будет работать на всех unices, вам придется использовать "expr" и " while", и это потому, что "(())" или "seq " или "i=i+1" не очень переносимы между различными оболочками
Я постоянно использую его варианты для обработки файлов...
для файлов в формате *.log;do echo "Делайте что-нибудь с:$файлы";echo "Делайте больше вещей с помощью:$файлы";сделанный;
Если вас интересует обработка списков файлов, загляните в раздел -execdir вариант для файлы.