问题
In bash, this works:
echo -n $'a\nb\nc\n' | while read x; do echo = $x =; done
The while loops through three times
= a =
= b =
= c =
But imagine a text file that doesn't have the conventional trailing newline. I think that read
should still work for all three lines, but it doesn't. I just get:
echo -n $'a\nb\nc' | while read x; do echo = $x =; done
= a =
= b =
The help read
in bash doesn't really clarify.
Note: I don't need this resolved, and I can see some ways to fix it myself. I am curious, and I am tempted to file a bug report - I generally try myself to respect files that mightn't have the trailing new line. I came across this when using the -d option to read. read -d " "
will split on spaces instead of newlines, but it will miss out on the last entry unless it has a trailing space.
(Ubuntu. GNU bash, version 4.1.5(1)-release)
回答1:
$ man bash
read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
One line is read from the standard input, ...
I think the key is: How to define "One line"
.
Does text without a '\n' at the end
makes One line
?
I guess read
don't think so.
回答2:
If you want the above loop to process the incomplete line, do this:
echo -n $'a\nb\nc' | while read x || [[ $x ]]; do echo = $x =; done
which gives:
= a =
= b =
= c =
When read
encounters the incomplete line, it does read that into the variable (x
in this case) but returns a non-zero exit code which would end the loop, and || [[ $x ]]
takes care of running the loop for the incomplete line as well. When read
is called the next time, there is nothing to read and it exits with 1, setting x
to an empty string as well, which ensures that we end the loop.
Related
- Looping through the content of a file in Bash
来源:https://stackoverflow.com/questions/8598980/trailing-newlines-and-the-bash-read-builtin