Как написать цикл for в bash

Я ищу базовый цикл, например:

for(int i = 0; i < MAX; i++) {
  doSomething(i);
}

но для bash.

Ответ 2

for ((i = 0 ; i < max ; i++ )); do echo "$i"; done

Ответ 3

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

Возможности для создания списков бесконечны.

Ответ 4

Bash 3.0+ может использовать этот синтаксис:

for i in {1..10} ; do ... ; done

.., который позволяет избежать появления внешней программы для расширения последовательности (например, seq 1 10).

Конечно, это имеет ту же проблему, что и решение for(()), привязанное к bash и даже к определенной версии (если это имеет к вам значение).

Ответ 5

Попробуйте встроенную справку 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.


Ответ 6

Мне обычно нравится использовать небольшой вариант для стандартного цикла. Я часто использую это для запуска команды на нескольких удаленных хостах. Я использую расширение 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; более ранние версии не поддержат это.

Ответ 7

#! /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?

Ответ 8

если вы перегружены только в bash, то "for ((...))" решение, представленное выше, является лучшим, но если вы хотите что-то совместимое с POSIX SH, которое будет работать на всех устройствах, вам придется используйте "expr" и "while", а потому, что "(())" или "seq" или "i = я + 1" не являются переносимыми между различными оболочками

Ответ 9

Я использую вариации этого времени для обработки файлов...

для файлов в *.log; do echo "Делать вещи с помощью: $files"; echo "Сделайте больше вещей с помощью: $files"; сделано;

Если вы хотите обработать списки файлов, просмотрите опцию -execdir для файлов.