Ответ 1
Это описано в разделе Bash FAQ в чтении данных по очереди.
Команда чтения изменяет каждую прочитанную строку; по умолчанию он удаляет все ведущие и завершающие пробельные символы (пробелы и вкладки или любые символы пробелов, присутствующие в IFS). Если это нежелательно, переменная IFS должна быть очищена:
# Exact lines, no trimming while IFS= read -r line; do printf '%s\n' "$line" done < "$file"
Как правильно указывает Чарльз Даффи (и я пропустил, сосредоточившись на проблеме IFS
); если вы хотите увидеть пробелы в своем выходе, вам также нужно указать переменную, когда вы ее используете, или оболочка снова сбросит пробелы.
Заметки о некоторых других различиях в цитированном фрагменте по сравнению с исходным кодом.
Использование аргумента -r
для read
рассматривается в одном предложении в верхней части ранее связанной страницы.
Параметр -r для чтения предотвращает интерпретацию обратной косой черты (обычно используется как пара новой строки обратной косой черты, для продолжения работы по нескольким строкам). Без этой опции любые обратные косые черты на входе будут отброшены. Вы должны почти всегда использовать параметр -r с чтением.
Что касается использования printf
вместо echo
, то поведение echo
, к сожалению, непропорционально согласовано во всех средах, и различия могут быть неудобны для решения. printf
, с другой стороны, согласован и может быть использован полностью надежно.