My script
export IFS=":"
cat hello | while read a b c d; do
echo $a,$b,$c,$d
done
My file hello
1:1:1:1
2:2:2:2
3:3:3:3
My output
1,1,1,1
2,2,2,2
If I put a blank line after 3:3:3:3
in hello
then the output becomes
1,1,1,1
2,2,2,2
3,3,3,3
Anyone know how I can fix this problem so I don't need to put a blank line at the end of hello
?
To look at the last few lines of a file, use the tail command. tail works the same way as head: type tail and the filename to see the last 10 lines of that file, or type tail -number filename to see the last number lines of the file.
tail [OPTION]... [ Tail is a command which prints the last few number of lines (10 lines by default) of a certain file, then terminates. Example 1: By default “tail” prints the last 10 lines of a file, then exits.
Then, the first line would be ${lines[0]} , and the last line would be ${lines[-1]} . In older versions of bash , negative indices aren't allowed and you'll have to compute the last index manually: ${lines[${#lines[@]}-1]} .
What's happening is, the read
command fails when the input is not terminated with a newline. Since the newline character is missing at the end of your file, the read
fails, so the last iteration of the while
loop is skipped.
If you don't want to / cannot make sure that your input file has a newline at the end, you can group your cat
with an echo
to give the appearance of an input terminated by newline, for example like this:
{ cat hello; echo; } | while read a b c d; do
echo $a,$b,$c,$d
done
or like this:
(cat hello; echo) | while read a b c d; do
echo $a,$b,$c,$d
done
This is an extensive reading for the question why?
If you don't want to put a new line at the end, you can do this:
while IFS=: read -r a b c d || [ -n "$a" ];
do
echo $a,$b,$c,$d;
done < file
Or using grep
:
while IFS=: read -r a b c d;
do
echo $a,$b,$c,$d;
done < <(grep "" filee)
Note:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With