Bash цикл for: перебор чисел, файлов и элементов массива
Цикл for в Bash перебирает значения: for i in 1 2 3; do echo "$i"; done. Диапазон задаётся записью {1..10}, файлы перебираются маской *.txt, а элементы массива перебираются через "${arr[@]}".
Перебор списка значений
for fruit in яблоко груша слива; do
echo "Фрукт: $fruit"
doneТа же запись в одну строку:
for fruit in яблоко груша слива; do echo "Фрукт: $fruit"; doneДиапазон чисел
for i in {1..5}; do echo "$i"; done # 1 2 3 4 5
for i in {0..20..5}; do echo "$i"; done # с шагом 5: 0 5 10 15 20
for i in $(seq 1 3); do echo "$i"; done # через seq, работает и с переменнымиЗапись {1..N} не принимает переменные: {1..$n} не сработает. В таком случае используйте seq 1 "$n" или цикл в стиле C.
Цикл в стиле C
n=4
for ((i = 1; i <= n; i++)); do
echo "шаг $i"
doneПеребор файлов
for file in /tmp/demo/*.txt; do
echo "Файл: $file ($(wc -l < "$file") строк)"
doneКавычки вокруг $file обязательны: без них имена с пробелами разобьются на части. Если подходящих файлов нет, Bash оставит в переменной сам шаблон. Проверьте это:
for file in /tmp/demo/*.csv; do
[ -e "$file" ] || continue # пропустить, если ничего не найдено
echo "$file"
doneЭлементы массива
servers=("web-1" "web-2" "db 1")
for server in "${servers[@]}"; do
echo "Проверяю: $server"
done
echo "Всего: ${#servers[@]}"Запись "${servers[@]}" в кавычках сохраняет элементы с пробелами, как db 1.
Прервать или пропустить шаг
for i in {1..10}; do
(( i % 2 == 0 )) && continue # пропустить чётные
(( i > 7 )) && break # остановиться после 7
echo "$i"
doneСтроки файла: не for, а while
Для чтения файла построчно for не подходит, потому что делит текст по пробелам. Используйте while read:
while IFS= read -r line; do
echo "Строка: $line"
done < /tmp/demo/a.txtЧастые вопросы
Почему for i in {1..$n} не работает?
Расширение фигурных скобок выполняется до подстановки переменных. Используйте seq или for ((i=1; i<=n; i++)).
Как использовать результат команды в цикле?
for pid in $(pgrep nginx); do ... подходит для коротких списков без пробелов в значениях. Для остальных случаев используйте while read и mapfile.