9

Чтение файла построчно с присвоением значения переменной

7

У меня есть следующий файл .txt:

Marco
Paolo
Antonio

Я хочу прочитать его построчно и для каждой строки назначить значение строчки переменной. Предположим, моя переменная - это $name, тогда последовательность действий будет следующей:

  1. Прочитать первую строку из файла.
  2. Присвоить $name значение "Marco".
  3. Выполнить некоторые действия с $name.
  4. Прочитать вторую строку из файла.
  5. Присвоить $name значение "Paolo".

Почему не удается реализовать этот процесс в Bash? Есть ли готовые решения для подобной задачи? Заранее благодарю за помощь!

5 ответ(ов)

3

Я рекомендую использовать флаг -r для команды read, который означает:

-r  Не обрабатывать символ обратного слэша каким-либо особым образом. Рассматривать каждый
    обратный слэш как часть входной строки.

Я цитирую из документации man 1 read.

Еще один момент — передать имя файла в качестве аргумента.

Вот обновленный код:

#!/usr/bin/bash
filename="$1"
while read -r line; do
    name="$line"
    echo "Имя, прочитанное из файла - $name"
done < "$filename"

Таким образом, все символы, включая обратные слэши, будут правильно обработаны, и вы сможете легко считывать содержимое файла.

1

Вы можете использовать следующий шаблон Bash для чтения значений из файла по одному и их дальнейшей обработки:

while read name; do
    # Выполните необходимые действия с $name
done < filename

Этот код открывает файл filename и считывает содержимое построчно, сохраняя каждую строку в переменной name. Вы можете заменить комментарий на любую необходимую обработку данных.

1

Ваш скрипт Bash считывает содержимое файла filename построчно и выводит каждую строку в терминал. Вот пояснение:

#! /bin/bash
cat filename | while read LINE; do
    echo $LINE
done

Пояснение:

  • #! /bin/bash: Указывает, что скрипт должен выполняться с использованием интерпретатора Bash.
  • cat filename: Команда cat считывает содержимое файла filename.
  • |: Этот символ представляет собой конвейер, который передает вывод команды слева как вход для команды справа.
  • while read LINE; do: Цикл while используется для построчного чтения данных. Каждая строка из cat будет присваиваться переменной LINE.
  • echo $LINE: Эта команда выводит значение переменной LINE, то есть текущую строку файла.

Замечание:

Использование cat в данном случае не является необходимым. Можно упростить этот код, записав его так:

while read LINE; do
    echo $LINE
done < filename

Это делает то же самое, но без использования cat. Такой подход более эффективен, так как он избегает создания дополнительного процесса.

0

Ваш код считывает строки из файла, переданного в качестве аргумента, и выводит каждую строку с указанием источника (имени файла). Однако, важно помнить о том, что переменная окружения IFS (Internal Field Separator - разделитель полей) играет значительную роль в разборе входных данных. Если вы измените значение IFS, вы можете получить неожиданные результаты.

Вот ваш код с подробным пояснением:

filename=$1             # Получаем имя файла из первого аргумента скрипта
IFS=$'\n'               # Устанавливаем IFS на новую строку, чтобы правильно разделять строки
for next in `cat $filename`; do  # Цикл по всем строкам файла
    echo "$next read from $filename"  # Выводим текущую строку и имя файла
done
exit 0                # Успешное завершение скрипта

Если вы измените IFS на что-то другое (например, пробелы или символы табуляции), это может привести к тому, что строки будут разделяться по другим критериям, и вы получите непредсказуемые результаты. Например, если в строке содержится пробел и вы установите IFS в пробел, то эта строка будет разбита на несколько частей.

Чтобы избежать проблем, рекомендуется возвращать IFS к его начальному значению после завершения работы с файлом, например:

OLDIFS=$IFS  # Сохраняем старое значение IFS
IFS=$'\n'    # Устанавливаем новый разделитель

# Ваш код...

IFS=$OLDIFS   # Восстанавливаем старое значение IFS

Это поможет гарантировать, что влияние на IFS будет локальным, и остальная часть вашего скрипта не будет затронута.

0

Многие пользователи публиковали решения, которые избыточно оптимизированы. Я не считаю их неправильными, но скромно полагаю, что менее оптимизированное решение будет более желательным, чтобы всем было проще понять, как оно работает. Вот мое предложение:

#!/bin/bash
#
# Эта программа читает строки из файла.
#

end_of_file=0
while [[ $end_of_file == 0 ]]; do
  read -r line
  # последний статус выхода является 
  # индикатором конца файла
  end_of_file=$?
  echo $line
done < "$1"

Это решение читается проще и дает ясное представление о том, как работает цикл чтения строк из файла.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь