What does `while read -r line || [[ -n $line ]]` mean?
Clash Royale CLAN TAG#URR8PPP
up vote
1
down vote
favorite
I found some code for reading input from a file a while ago, I believe from Stack Exchange, that I was able to adapt for my needs:
while read -r line || [[ -n "$line" ]]; do
if [[ $line != "" ]]
then
((x++));
echo "$x: $line"
<then do something with $line>
fi
done < "$1"
I'm reviewing my script now & trying to understand what it's doing ... I don't understand what this statement is doing:
while read -r line || [[ -n "$line" ]];
I understand that the -r option says that we're reading raw text into line, but I'm confused about the || [[ -n "$line" ]]
portion of the statement. Can someone please explain what that is doing?
read
New contributor
add a comment |Â
up vote
1
down vote
favorite
I found some code for reading input from a file a while ago, I believe from Stack Exchange, that I was able to adapt for my needs:
while read -r line || [[ -n "$line" ]]; do
if [[ $line != "" ]]
then
((x++));
echo "$x: $line"
<then do something with $line>
fi
done < "$1"
I'm reviewing my script now & trying to understand what it's doing ... I don't understand what this statement is doing:
while read -r line || [[ -n "$line" ]];
I understand that the -r option says that we're reading raw text into line, but I'm confused about the || [[ -n "$line" ]]
portion of the statement. Can someone please explain what that is doing?
read
New contributor
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I found some code for reading input from a file a while ago, I believe from Stack Exchange, that I was able to adapt for my needs:
while read -r line || [[ -n "$line" ]]; do
if [[ $line != "" ]]
then
((x++));
echo "$x: $line"
<then do something with $line>
fi
done < "$1"
I'm reviewing my script now & trying to understand what it's doing ... I don't understand what this statement is doing:
while read -r line || [[ -n "$line" ]];
I understand that the -r option says that we're reading raw text into line, but I'm confused about the || [[ -n "$line" ]]
portion of the statement. Can someone please explain what that is doing?
read
New contributor
I found some code for reading input from a file a while ago, I believe from Stack Exchange, that I was able to adapt for my needs:
while read -r line || [[ -n "$line" ]]; do
if [[ $line != "" ]]
then
((x++));
echo "$x: $line"
<then do something with $line>
fi
done < "$1"
I'm reviewing my script now & trying to understand what it's doing ... I don't understand what this statement is doing:
while read -r line || [[ -n "$line" ]];
I understand that the -r option says that we're reading raw text into line, but I'm confused about the || [[ -n "$line" ]]
portion of the statement. Can someone please explain what that is doing?
read
read
New contributor
New contributor
edited 15 mins ago
muru
34.4k579149
34.4k579149
New contributor
asked 7 hours ago
K. Hilbert
83
83
New contributor
New contributor
add a comment |Â
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
1
down vote
accepted
[[ -n "$line" ]]
tests if $line
(the variable just read by read
) is not empty. It's useful since read
returns a success if and only if it sees a newline character before the end-of-file. If the input contains a line fragment without a newline in the end, this test will catch that, and the loop will process that final incomplete line, too. Without the extra test, such an incomplete line would be read into $line
, but ignored by the loop.
The cmd1 ||ÃÂ cmd2
construct is of course just like the equivalent in C. The second command runs if the first returns a falsy status, and the result is the exit status of the last command that executed.
Compare:
$ printf 'foonbar' | ( while read line; do echo "in loop: $line" ; done ; echo "finally: $line" )
in loop: foo
finally: bar
and
$ printf 'foonbar' | ( while read line || [[ -n $line ]]; do echo "in loop: $line" ; done ; echo "finally: $line" )
in loop: foo
in loop: bar
finally:
A missing LF at EOF totally slipped my mind. Good catch on that...
â brhfl
5 hours ago
Thank you both for your answers ... that clears it up.
â K. Hilbert
5 hours ago
add a comment |Â
up vote
1
down vote
It's a bit confusing as to why that would be there, but straightforward to explain what it does: ||
is an OR statement, and [[ -n
returns true (success) as long as "$line"
has a nonzero length. Here's what's confusing: while loops keep going while there's a successful (0) exit status. read
continues to read lines and return a 0 exit status until it hits end of file -- even if those lines are blank. [[ -n "$line" ]]
is only going to execute when read
returns a nonzero exit code, at which point $line
will be empty. Since the test returns true if $line
is not empty, we're back to a nonzero exit, throwing us out of the while
loop. As far as I can see, (As @ilkkachu pointed out, this will catch the odd final line of input that is missing its trailing newline. Note that such a file is not a valid text file, as that line is not a valid line)|| [[ -n "$line" ]]
doesn't actually accomplish anything.
Something that is occasionally useful is to do while read -r line && [[ -n "$line" ]]
. Using &&
(AND) means that the whole statement will only return a zero status if read
is able to read a line, AND that line is not empty. It will cause the while
loop to halt at the first empty line. If I had to make a guess, this snippet of code may have been adapted from one which did just that - and instead of simply removing the test, the author changed the &&
to ||
.
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
[[ -n "$line" ]]
tests if $line
(the variable just read by read
) is not empty. It's useful since read
returns a success if and only if it sees a newline character before the end-of-file. If the input contains a line fragment without a newline in the end, this test will catch that, and the loop will process that final incomplete line, too. Without the extra test, such an incomplete line would be read into $line
, but ignored by the loop.
The cmd1 ||ÃÂ cmd2
construct is of course just like the equivalent in C. The second command runs if the first returns a falsy status, and the result is the exit status of the last command that executed.
Compare:
$ printf 'foonbar' | ( while read line; do echo "in loop: $line" ; done ; echo "finally: $line" )
in loop: foo
finally: bar
and
$ printf 'foonbar' | ( while read line || [[ -n $line ]]; do echo "in loop: $line" ; done ; echo "finally: $line" )
in loop: foo
in loop: bar
finally:
A missing LF at EOF totally slipped my mind. Good catch on that...
â brhfl
5 hours ago
Thank you both for your answers ... that clears it up.
â K. Hilbert
5 hours ago
add a comment |Â
up vote
1
down vote
accepted
[[ -n "$line" ]]
tests if $line
(the variable just read by read
) is not empty. It's useful since read
returns a success if and only if it sees a newline character before the end-of-file. If the input contains a line fragment without a newline in the end, this test will catch that, and the loop will process that final incomplete line, too. Without the extra test, such an incomplete line would be read into $line
, but ignored by the loop.
The cmd1 ||ÃÂ cmd2
construct is of course just like the equivalent in C. The second command runs if the first returns a falsy status, and the result is the exit status of the last command that executed.
Compare:
$ printf 'foonbar' | ( while read line; do echo "in loop: $line" ; done ; echo "finally: $line" )
in loop: foo
finally: bar
and
$ printf 'foonbar' | ( while read line || [[ -n $line ]]; do echo "in loop: $line" ; done ; echo "finally: $line" )
in loop: foo
in loop: bar
finally:
A missing LF at EOF totally slipped my mind. Good catch on that...
â brhfl
5 hours ago
Thank you both for your answers ... that clears it up.
â K. Hilbert
5 hours ago
add a comment |Â
up vote
1
down vote
accepted
up vote
1
down vote
accepted
[[ -n "$line" ]]
tests if $line
(the variable just read by read
) is not empty. It's useful since read
returns a success if and only if it sees a newline character before the end-of-file. If the input contains a line fragment without a newline in the end, this test will catch that, and the loop will process that final incomplete line, too. Without the extra test, such an incomplete line would be read into $line
, but ignored by the loop.
The cmd1 ||ÃÂ cmd2
construct is of course just like the equivalent in C. The second command runs if the first returns a falsy status, and the result is the exit status of the last command that executed.
Compare:
$ printf 'foonbar' | ( while read line; do echo "in loop: $line" ; done ; echo "finally: $line" )
in loop: foo
finally: bar
and
$ printf 'foonbar' | ( while read line || [[ -n $line ]]; do echo "in loop: $line" ; done ; echo "finally: $line" )
in loop: foo
in loop: bar
finally:
[[ -n "$line" ]]
tests if $line
(the variable just read by read
) is not empty. It's useful since read
returns a success if and only if it sees a newline character before the end-of-file. If the input contains a line fragment without a newline in the end, this test will catch that, and the loop will process that final incomplete line, too. Without the extra test, such an incomplete line would be read into $line
, but ignored by the loop.
The cmd1 ||ÃÂ cmd2
construct is of course just like the equivalent in C. The second command runs if the first returns a falsy status, and the result is the exit status of the last command that executed.
Compare:
$ printf 'foonbar' | ( while read line; do echo "in loop: $line" ; done ; echo "finally: $line" )
in loop: foo
finally: bar
and
$ printf 'foonbar' | ( while read line || [[ -n $line ]]; do echo "in loop: $line" ; done ; echo "finally: $line" )
in loop: foo
in loop: bar
finally:
edited 5 hours ago
answered 6 hours ago
ilkkachu
53.2k780146
53.2k780146
A missing LF at EOF totally slipped my mind. Good catch on that...
â brhfl
5 hours ago
Thank you both for your answers ... that clears it up.
â K. Hilbert
5 hours ago
add a comment |Â
A missing LF at EOF totally slipped my mind. Good catch on that...
â brhfl
5 hours ago
Thank you both for your answers ... that clears it up.
â K. Hilbert
5 hours ago
A missing LF at EOF totally slipped my mind. Good catch on that...
â brhfl
5 hours ago
A missing LF at EOF totally slipped my mind. Good catch on that...
â brhfl
5 hours ago
Thank you both for your answers ... that clears it up.
â K. Hilbert
5 hours ago
Thank you both for your answers ... that clears it up.
â K. Hilbert
5 hours ago
add a comment |Â
up vote
1
down vote
It's a bit confusing as to why that would be there, but straightforward to explain what it does: ||
is an OR statement, and [[ -n
returns true (success) as long as "$line"
has a nonzero length. Here's what's confusing: while loops keep going while there's a successful (0) exit status. read
continues to read lines and return a 0 exit status until it hits end of file -- even if those lines are blank. [[ -n "$line" ]]
is only going to execute when read
returns a nonzero exit code, at which point $line
will be empty. Since the test returns true if $line
is not empty, we're back to a nonzero exit, throwing us out of the while
loop. As far as I can see, (As @ilkkachu pointed out, this will catch the odd final line of input that is missing its trailing newline. Note that such a file is not a valid text file, as that line is not a valid line)|| [[ -n "$line" ]]
doesn't actually accomplish anything.
Something that is occasionally useful is to do while read -r line && [[ -n "$line" ]]
. Using &&
(AND) means that the whole statement will only return a zero status if read
is able to read a line, AND that line is not empty. It will cause the while
loop to halt at the first empty line. If I had to make a guess, this snippet of code may have been adapted from one which did just that - and instead of simply removing the test, the author changed the &&
to ||
.
add a comment |Â
up vote
1
down vote
It's a bit confusing as to why that would be there, but straightforward to explain what it does: ||
is an OR statement, and [[ -n
returns true (success) as long as "$line"
has a nonzero length. Here's what's confusing: while loops keep going while there's a successful (0) exit status. read
continues to read lines and return a 0 exit status until it hits end of file -- even if those lines are blank. [[ -n "$line" ]]
is only going to execute when read
returns a nonzero exit code, at which point $line
will be empty. Since the test returns true if $line
is not empty, we're back to a nonzero exit, throwing us out of the while
loop. As far as I can see, (As @ilkkachu pointed out, this will catch the odd final line of input that is missing its trailing newline. Note that such a file is not a valid text file, as that line is not a valid line)|| [[ -n "$line" ]]
doesn't actually accomplish anything.
Something that is occasionally useful is to do while read -r line && [[ -n "$line" ]]
. Using &&
(AND) means that the whole statement will only return a zero status if read
is able to read a line, AND that line is not empty. It will cause the while
loop to halt at the first empty line. If I had to make a guess, this snippet of code may have been adapted from one which did just that - and instead of simply removing the test, the author changed the &&
to ||
.
add a comment |Â
up vote
1
down vote
up vote
1
down vote
It's a bit confusing as to why that would be there, but straightforward to explain what it does: ||
is an OR statement, and [[ -n
returns true (success) as long as "$line"
has a nonzero length. Here's what's confusing: while loops keep going while there's a successful (0) exit status. read
continues to read lines and return a 0 exit status until it hits end of file -- even if those lines are blank. [[ -n "$line" ]]
is only going to execute when read
returns a nonzero exit code, at which point $line
will be empty. Since the test returns true if $line
is not empty, we're back to a nonzero exit, throwing us out of the while
loop. As far as I can see, (As @ilkkachu pointed out, this will catch the odd final line of input that is missing its trailing newline. Note that such a file is not a valid text file, as that line is not a valid line)|| [[ -n "$line" ]]
doesn't actually accomplish anything.
Something that is occasionally useful is to do while read -r line && [[ -n "$line" ]]
. Using &&
(AND) means that the whole statement will only return a zero status if read
is able to read a line, AND that line is not empty. It will cause the while
loop to halt at the first empty line. If I had to make a guess, this snippet of code may have been adapted from one which did just that - and instead of simply removing the test, the author changed the &&
to ||
.
It's a bit confusing as to why that would be there, but straightforward to explain what it does: ||
is an OR statement, and [[ -n
returns true (success) as long as "$line"
has a nonzero length. Here's what's confusing: while loops keep going while there's a successful (0) exit status. read
continues to read lines and return a 0 exit status until it hits end of file -- even if those lines are blank. [[ -n "$line" ]]
is only going to execute when read
returns a nonzero exit code, at which point $line
will be empty. Since the test returns true if $line
is not empty, we're back to a nonzero exit, throwing us out of the while
loop. As far as I can see, (As @ilkkachu pointed out, this will catch the odd final line of input that is missing its trailing newline. Note that such a file is not a valid text file, as that line is not a valid line)|| [[ -n "$line" ]]
doesn't actually accomplish anything.
Something that is occasionally useful is to do while read -r line && [[ -n "$line" ]]
. Using &&
(AND) means that the whole statement will only return a zero status if read
is able to read a line, AND that line is not empty. It will cause the while
loop to halt at the first empty line. If I had to make a guess, this snippet of code may have been adapted from one which did just that - and instead of simply removing the test, the author changed the &&
to ||
.
edited 5 hours ago
answered 6 hours ago
brhfl
1634
1634
add a comment |Â
add a comment |Â
K. Hilbert is a new contributor. Be nice, and check out our Code of Conduct.
K. Hilbert is a new contributor. Be nice, and check out our Code of Conduct.
K. Hilbert is a new contributor. Be nice, and check out our Code of Conduct.
K. Hilbert is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f478720%2fwhat-does-while-read-r-line-n-line-mean%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password