Сценарий оболочки не читает последнюю строку из sysin
Я пытаюсь получить некоторые данные из sysin, и вот моя проблема: если данные направлены из файла, то последняя строка не читается. Пример текстового файла:
line1
line2
line3
Мой код:
#!/bin/bash
while read line
do
echo "$line"
done
И вывод:
$ ./test.sh < data.txt
line1
line2
Если я записываю в конце моего файла, вывод пустой строки будет правильным. Но мне это не нравится. Как это исправить?
3 ответа
Если вам отчаянно нужно прочитать файлы без EOL, вы можете проверить, является ли возвращенная строка пустой или нет, вместо проверки read
статус выхода:
#!/bin/bash
while true; do
line=''
read line
if [ -z "$line" ]; then
break
fi
echo "$line"
done
Идиома для этого:
while read -r line || [[ $line ]]; do
: process "$line"
done
Таким образом, мы продолжаем цикл пока либо:
- Мы читаем правильную строку текста (которая требует новой строки)
- У нас было частичное чтение (что приводит к ненулевому состоянию выхода, но оставляет переменную непустой).
Могу поспорить, что в data.txt отсутствует завершающий символ новой строки, попробуйте проверить с помощью
od -xa data.txt
Посмотрите на конец:
$ od -xa data.txt
0000000 696c 656e 0a31 696c 656e 0a32 696c 656e
l i n e 1 nl l i n e 2 nl l i n e
0000020 0033
3
0000021
Если вы видите выше, вам не хватает новой строки.
$ od -xa data-with-nl.txt
0000000 696c 656e 0a31 696c 656e 0a32 696c 656e
l i n e 1 nl l i n e 2 nl l i n e
0000020 0a33
3 nl
0000022
Некоторые снаряды также покажут %
подпишите, если завершающий символ новой строки отсутствует, попробуйте:
$ cat data.txt
line1
line2
line3%
$