Как читать файл построчно в Bash

При написании сценариев 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 интерпретирует обратную косую черту как escape-символ и удаляет все начальные и конечные пробелы, что иногда может вызвать неожиданное поведение. Чтобы отключить экранирование обратной косой черты, мы вызываем команду с параметром -r , а чтобы отключить обрезку, внутренний разделитель полей ( IFS ) очищается.

Мы используем [ printf ] вместо echo чтобы сделать код более переносимым и избежать нежелательного поведения. Например, если строка содержит такие значения, как «-e», она будет рассматриваться как опция эха.

Примеры чтения файла построчно

Давайте посмотрим на следующий пример. Предположим, у нас есть файл с именем 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

Здесь String — это вариант документа Here . Строка (cat input_file ) сохраняет (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 .

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.

Оставьте комментарий