POSIX sh: Как я могу прочитать весь файл в одну строку, используя только оболочку, сохраняя пробелы и переводы строки в исходном файле? - PullRequest
0 голосов
/ 21 мая 2018

Прежде чем все сойдут с ума и скажут, что это дубликат, я хотел бы отметить, что, хотя существует много вопросов о построчном чтении файла, ни один из найденных мною вопросов не касается хранения всего файла в одной переменной.Скорее, большинство вопросов, по-видимому, касаются выполнения каких-либо операций с каждой строкой во время их чтения. В качестве примера рассмотрим следующее:

#!/bin/sh

while IFS='' read -r line || [ -n "$line" ]; do
    echo "$line"
done < file

Мне кажется, я не могу это реализоватьдля моей конкретной цели.Когда я делаю следующее:

#!/bin/sh

newline='
'

string=''
while IFS='' read -r line || [ -n "$line" ]; do
    string="$string""$line""$newline"
done < file

echo "$string"

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

1 Ответ

0 голосов
/ 22 мая 2018

Вы безоговорочно добавляете новую строку с назначением string="$string""$line""$newline".

read возвращает значение true, если оно успешно считывает строку, включая символ новой строки.Проверка того, содержит ли $line что-либо, имеет дело с возможным последним фрагментом строки.Но когда вы его обрабатываете, вам нужно , а не добавить символ новой строки, поскольку его там не было с самого начала.Пока нет окончательного фрагмента строки, ваш скрипт работает нормально.

Вероятно, это легче всего исправить, переместив тест [ -n "$line" ] за пределы цикла:

#!/bin/sh
newline='
'
string=
while IFS= read -r line; do
    string="$string$line$newline"
done < "$1"
if [ "$line" ]; then
    string="$string$line"
fi

echo "<$string>"       # markers for clarity

Конечно, это также можетбудь то, что входной файл имеет только полные строки, а дополнительный символ новой строки - это то, что печатает echo.Используйте printf "%s" "$string", чтобы напечатать только содержимое переменной, без новой строки или чего-либо еще.У некоторых оболочек есть echo -n, чтобы запретить заключительный перевод строки, но это нестандартно.

...