
При написании Bash-скриптов иногда возникают ситуации, когда требуется читать файл построчно. Например, у вас может быть текстовый файл с данными, которые должен обработать скрипт.
В этом уроке мы обсудим, как читать файл построчно в Bash.
Чтение файла построчно. Синтаксис
Наиболее общий синтаксис для построчного чтения файла выглядит следующим образом:
while IFS = read -r line ; do printf '%sn' " $line " done < input_file
или эквивалентная однострочная версия:
while IFS = read -r line ; do printf '%sn' " $line " ; done < input_file
Как это работает?
Входной файл ( input_file ) — это имя файла, перенаправленного в цикл while. Команда read обрабатывает файл построчно, присваивая каждую строку переменной line . После обработки всех строк цикл while завершается.
По умолчанию команда read интерпретирует обратную косую черту как экранирующий символ и удаляет все начальные и конечные пробелы, что иногда может приводить к непредсказуемому поведению. Чтобы отключить экранирование обратной косой черты, мы вызываем команду с опцией -r , а для отключения обрезки внутренний разделитель полей ( IFS ) очищается.
Мы используем [ printf ] вместо echo , чтобы сделать код более переносимым и избежать нежелательного поведения. Например, если строка содержит такие значения, как «-e», она будет воспринята как опция echo.
Примеры построчного чтения файла
Рассмотрим следующий пример. Предположим, у нас есть файл distros.txt , содержащий список некоторых самых популярных дистрибутивов Linux и их менеджеров пакетов, разделённых запятыми ( , ):
distros.txt
Ubuntu,apt Debian,apt CentOS,yum Arch Linux,pacman Fedora,dnf
Чтобы прочитать файл построчно, вам нужно запустить следующий код в терминале:
while IFS = read -r line ; do printf '%sn' " $line " done < distros.txt
Код считывает файл построчно, присваивает каждую строку переменной и выводит её на экран. По сути, вы увидите тот же результат, что и при выводе содержимого файла с помощью команды cat .
Что делать, если нужно вывести только дистрибутивы, использующие apt? Один из способов — использовать оператор if и проверить, содержит ли строка подстроку apt:
while IFS = read -r line ; do if [[ " $line " == * "apt" * ]] ; then printf '%sn' " $line " fi done < distros.txt
Ubuntu,apt Debian,apt
При построчном чтении файла можно также передать команде read несколько переменных, что разобьёт строку на поля по правилу IFS . Первое поле будет присвоено первой переменной, второе — второй и т. д. Если полей больше, чем переменных, оставшиеся поля будут присвоены последней переменной.
В следующем примере мы устанавливаем IFS в запятую ( , ) и передаем две переменные distro и pm команде read . Всё от начала строки до первой запятой будет присвоено первой переменной ( distro ), а остальная часть строки — второй переменной ( pm ):
while IFS = , read -r distro pm ; do printf '%s is the package manager for %sn' " $pm " " $distro " done < distros.txt
apt is the package manager for Ubuntu apt is the package manager for Debian yum is the package manager for CentOS pacman is the package manager for Arch Linux dnf is the package manager for Fedora
Альтернативные методы чтения файлов
Использование замены процесса
Подстановка процесса — это функция, которая позволяет использовать вывод команды в виде файла:
while IFS = read -r line ; do printf '%sn' " $line " done < < ( cat input_file )
Использование строки Here
Here String — это вариант Here document . Строка (cat input_file ) сохраняет символы переноса строк:
while IFS = read -r line ; do printf '%sn' " $line " done <<< $( cat input_file )
Использование файлового дескриптора
Вы также можете предоставить входные данные для цикла, используя файловый дескриптор:
while IFS = read -r -u9 line ; do printf '%sn' " $line " done 9< input_file
При работе с файловыми дескрипторами используйте числа от 4 до 9, чтобы избежать конфликта с внутренними файловыми дескрипторами оболочки.
Заключение
В Bash мы можем читать файл построчно, используя цикл while и команду read .
Если у вас есть вопросы или пожелания, не стесняйтесь оставлять комментарии.
Связанные руководства