I'm learning about the read command and wrote this little script to read data from a file:
readfile()
{
while read variable; do
echo $variable
done
}
readfile < File.txt
I have three lines in File.txt; each a single word. The script only echoes the first two lines and drops the third one. Can anyone tell me why?
Also, what does the statment
if [ $variable ] mean? Does it mean 'if the value of variable exists....'?
can you post your File.txt?This code runs okay on my laptop.
I think [ $variable ] means to test if the value of variable is null or unset,if so,evaluated as false.use [ -n $variable ] or [ -z $variable ] will be better.
Sure can. Here is the file -- only three lines
Red
Blue
Green
It echoes Red and Blue but not green. Did it return all the lines in your file?
--Works fine for me too:
$ cat testit
readfile()
{
while read variable; do
echo $variable
done
}
readfile < File.txt
$ cat File.txt
one
two
three
$ ./testit
one
two
three
if [$variable ]
wont work as intended when $variable contains a space eg variable="one two"
, best to stick with:
if [ -n "$variable" ]
Never mind -- figured it out, although I feel like an idiot. :o
I saved the file without hitting return after the last word. Out of curiosity, can anyone tell me why that is?
Runs fine now.
:),interesting~Even without hitting return,i get three lines and if i hit return,it will print a blank line as expected.
read returns a non-zero if it encounters a END-OF-FILE char and zero if it encounters a CR char. variables are populated with anything that is read to this point.
You should probably do something like:
readfile()
{
while read variable; do
echo "$variable"
done
echo -e "${variable}\c"
}
Thanks, Chubler. But as I'm still learning about these things, could you explain the last few lines of code to me -- I mean the \c part? Zero is the successful exit status or is it 1, I forget.
the -e option of echo is a bash/ksh thing and enables the interpreation of backslash escapes. \c is used to suppress the CR at the end of a string.
So by echoing the variable with \c we duplicate the contents of the file by showing any value without a CR as it was input. Now, if no line exists without a CR at the end of the file, the variable will be blank and so we echo blank without a CR (i.e. nothing).
read returns 0 if more data is available (ie no EOF is read) and non-zero (typically 1) if and EOF is found.
Instead of echo -e you could use printf which works in other shells too:
printf "%s" "$variable"
Or if you do not want to preserve the non-linefeed ending of the last line (which is not a proper unix text file format)
while read variable || [ -n "$variable" ]; do
echo "$variable"
done