
Содержимое файла file.txt (ничего странного, текстовый файл, как определено POSIX)
iguana
gecko
anole
Пример сценария:
#!/bin/sh
string="$(cat file.txt)"
printf '%s' "$string"
Пример вывода:
[coolguy@somemachine ~]$ ./script.sh
iguana
gecko
anole[coolguy@somemachine ~]$
Что случилось с последней новой строкой? Почему все новые строки, кроме последней, сохранены? Похоже, нам не нужно использовать echo для добавления новой строки, если она уже должна быть.
решение1
Это не печать, это подстановка команды, которая делает это. Она определена, чтобы делать это. ИзОписание POSIX:
Оболочка должна расширить подстановку команды, выполнив команду в среде подоболочки и заменив подстановку команды стандартным выводом команды,удаление последовательностей из одного или нескольких символов {newline} в конце подстановки.
Обратите внимание, что он удаляетвсезавершающие символы новой строки, а не один.
В довольно распространенном случае вы бы использовали подстановку команд для захвата однострочного вывода, скажем osrev=$(uname -r)
. Утилиты обычно печатают завершающий символ новой строки для удобства пользователя в командной строке. Но в скрипте оболочки вы можете захотеть использовать эту строку как часть другой, скажем, имени файла: filename=blahblah-$osrev.dat
. И в этом случае завершающий символ новой строки будет только мешать.
И, конечно же, echo
в любом случае будет добавлен завершающий перевод строки.
Если вы хотите сохранить содержимое файла в переменной как есть, то распространенным решением будет добавить дополнительный символ в подстановку команды и удалить его позже:
printf "foo\nbar\n\n" > file
string=$(cat file; echo x)
string=${string%x}
printf '%q\n' "$string"
, который выводит $'foo\nbar\n\n'
, показывая наличие обоих конечных символов новой строки.
В зависимости от того, что вы собираетесь делать с данными, могут быть и другие способы. Например, while read
цикл или Bash's mapfile
, если вы хотите обрабатывать файл построчно.