Очень часто в bash скриптах требуется обрабатывать строки, для этого удобно использовать циклы while и for. В статье описан синтаксис обоих циклов для обработки строк, а также особенности их работы.
Оглавление
скрыть
Цикл while
Синтаксис:
<команда возвращающая строки> | while read line
do
<команда обрабатывающая строки> $line
done
Пример 1. Получаем список пользователей в системе:
#!/bin/bash
cat /etc/passwd | cut -f 1 -d ":" | while read line
do
echo "В системе есть пользователь - $line"
done
Пример 2. Выводим список процессов текущего пользователя:
#!/bin/bash
ps -u $USER -o pid | grep -v PID | while read line
do
ps -p $line -o pid,comm,rss -h
done
Особенности:
- Чтение происходит построчно, даже если строка содержит пробелы или специальные символы.
- Корректно обрабатывает строки с пробелами и табуляциями.
- Работает в подоболочке, поэтому переменные, измененные внутри цикла, не сохранятся в родительской оболочке.
- Подходит для обработки вывода команд, которые могут возвращать много данных (потоковая обработка).
- Для обработки строк предпочтительнее использовать этот вариант.
Цикл for
Синтаксис:
for line in `<команда возвращающая строки>`
do
<команда обрабатывающая строки> $line
done
Пример 1. Получаем список пользователей в системе:
#!/bin/bash
for line in `cat /etc/passwd | cut -f 1 -d ":"`
do
echo "В системе есть пользователь - $line"
done
Пример 2. Выводим список процессов текущего пользователя:
#!/bin/bash
for line in `ps -u $USER -o pid | grep -v PID`
do
ps -p $line -o pid,comm,rss -h
done
Особенности:
- Если строки содержат пробелы, они будут разбиты на отдельные «слова». Не подходит для обработки строк с пробелами.
- Выполняется в текущей оболочке (переменные сохраняются).
- Загружает весь вывод команды в память перед обработкой (может быть проблемой для больших данных).
- Используйте этот вариант только если нужно сохранить переменные после завершения цикла.
Кстати, когда данные уже находятся в массиве, for работает быстрее и проще:
files=(file1.txt file2.txt "file with space.txt")
for file in "${files[@]}"; do
echo "Обработка: $file"
done
Если понравилась статья, подпишись на мой канал в VK или Telegram.
Возможно вам понравятся и другие статьи: