Для того, чтобы прочитать текстовый файл в буквальном смысле, не используйте обычный read, который обрабатывает выход двумя способами:
readинтерпретирует \как побег персонажа; используйте, read -rчтобы отключить это.
readразбивается на слова по символам в $IFS; установите IFSпустую строку, чтобы отключить это.
Обычная идиома для обработки текстового файла построчно
while IFS= read -r line; do …
Для объяснения этой идиомы см. Почему while IFS= readиспользуется так часто, а не IFS=; while read..? ,
Чтобы записать строку буквально, не просто используйте plain echo, который обрабатывает строку двумя способами:
- На некоторых оболочках происходит
echoобратная косая черта. (На bash это зависит от того, установлена ли xpg_echoопция.)
- Несколько строк обрабатываются как опции, например,
-nили -e(точный набор зависит от оболочки).
Портативный способ печати строки буквально с printf. (В bash нет лучшего способа, если только вы не знаете, что ваш ввод не выглядит как вариант echo.) Используйте первую форму, чтобы напечатать точную строку, и вторую форму, если вы хотите добавить новую строку.
printf %s "$line"
printf '%s\n' "$line"
Это подходит только для обработки текста , потому что:
- Большинство оболочек будут подавлены нулевыми символами на входе.
- Когда вы прочитали последнюю строку, у вас нет возможности узнать, был ли перевод строки в конце или нет. (У некоторых старых оболочек могут возникнуть большие проблемы, если ввод не заканчивается новой строкой.)
Вы не можете обрабатывать двоичные данные в оболочке, но современные версии утилит в большинстве устройств могут справиться с произвольными данными. Чтобы передать весь ввод на выход, используйте cat. Переход по касательной echo -n ''- сложный и непереносимый способ ничего не делать; echo -nбудет таким же хорошим (или не зависящим от оболочки), :более простым и полностью переносимым.
: >| "$file"
cat >>"$file"
или, проще,
cat >|"$file"
В сценарии вам обычно не нужно использовать, >|так noclobberкак по умолчанию он выключен.