Thank you for reading this post, don't forget to subscribe!
При написании сценариев Bash вы иногда окажетесь в ситуациях, когда вам нужно читать файл построчно. Например, у вас может быть текстовый файл, содержащий данные, которые должны обрабатываться сценарием.
В этой статье мы расскажем о том, как построчно читать файл в Bash.
Считывание файла построчным синтаксисом
Наиболее общий синтаксис для чтения файла построчно:
1 2 3 4 |
while IFS= read -r line do echo "$line" done < input_file |
или эквивалентная однострочная версия:
1 |
while IFS= read -r line; do echo $line; done < input_file |
Как это работает?
Входной файл ( input_file) – это имя файла, который вы хотите открыть командой для чтения read. Команда readчитает файл построчно, присваивая каждую строку переменной line. Как только все строки обработаны, цикл while прекратится. Внутренний разделитель полей (IFS) устанавливается в пустую строку, чтобы сохранить начальные и конечные пробелы, что является поведением команды по умолчанию read.
Чтение файла построчные примеры
Давайте посмотрим на следующий пример. Предположим, у нас есть файл с именем, distros.txt содержащий список некоторых наиболее популярных дистрибутивов Linux и менеджеры пакетов, разделенные запятой (,):
1 2 3 4 5 |
Ubuntu,apt Debian,apt CentOS,yum Arch Linux,pacman Fedora,dnf |
Чтобы прочитать файл построчно, вы должны запустить следующий код в вашем терминале:
1 2 3 4 |
while IFS= read -r line do echo "$line" done < distros.txt |
<
Код будет читать файл построчно, назначать строку переменной и выводить ее. По простоте вы увидите тот же вывод, что и при отображении содержимого файла с помощью команды cat.
Что если вы хотите распечатать только дистрибутивы, которые используют apt? Один из способов – проверить, содержит ли строка подстроку apt :
1 2 3 4 5 6 |
while IFS= read -r line do if [[ "$line" == *"apt"* ]]; then echo "$line" fi done < distros.txt |
1 2 |
Ubuntu,apt Debian,apt |
При чтении файла строка за строкой вы также можете передать более одной переменной в команду чтения, которая разделит строку на поля на основе IFS. Первое поле присваивается первой переменной, второе – второй переменной и т. д. Если полей больше, чем переменных, оставшиеся поля присваиваются последней переменной.
В следующем примере мы устанавливаем IFS для запятой (,) и передаем две переменные distro и pm команде чтения. Все от начала строки до первой запятой будет присвоено первой переменной ( distro), а остальная часть строки будет назначена второй переменной ( pm):
1 2 3 4 |
while IFS=, read -r distro pm do echo "$pm" менеджер пакетов для "$distro" done < distros.txt |
1 2 3 4 5 |
apt менеджер пакетов для Ubuntu apt менеджер пакетов для Debian yum менеджер пакетов для CentOS pacman менеджер пакетов для Arch Linux dnf менеджер пакетов для Fedora |
Альтернативные методы чтения файлов
Использование процесса замены
Подстановка процесса позволяет вам передавать вывод команды в виде имени файла:
1 2 3 4 |
while IFS= read -r line do echo "$line" done < <(cat input_file ) |
Использование строки Here
Здесь Строка является вариантом документа Здесь. Строка (cat input_file ) будет содержать новые строки:
1 2 3 4 |
while IFS= read -r line do echo "$line" done <<< $(cat input_file ) |
Использование файлового дескриптора
Вы также можете предоставить вход для цикла, используя дескриптор файла:
1 2 3 4 |
while IFS= read -r -u9 line do echo "$line" done 9< input_file |
При работе с файловыми дескрипторами используйте число от 4 до 9, чтобы избежать конфликта с внутренними файловыми дескрипторами оболочки.