Способ, который работает во всех оболочках, следующий:
#!/bin/sh
willexit=0
while [ $willexit == 0 ] ; do
read ROW || willexit=1
...
done < file
Прямое while read
завершится, как только read
встретит EOF, поэтому последняя строка не будет обработана. Проверяя возвращаемое значение за пределами while, мы можем обработать последнюю строку. Тем не менее, после чтения следует добавить дополнительный тест на пустоту $ ROW, так как в противном случае файл, последняя строка которого заканчивается новой строкой, сгенерирует ложное выполнение с пустой строкой, поэтому сделайте его
#!/bin/sh
willexit=0
while [ $willexit == 0 ] ; do
read ROW || willexit=1
if [ -n "$ROW"] ; then
...
fi
done < file