Reputation: 10133
I found a bash script that lists all files with a blank line at the beginning or end of the file.
for f in `find . -type f`; do
for t in head tail; do
$t -1 $f |egrep '^[ ]*$' >/dev/null && echo "blank line at the $t of $f" ;
done;
done
I would like to pass the output to a file. I changed the echo
line to:
$t -1 $f |egrep '^[ ]*$' >/dev/null && echo "blank line at the $t of $f" > blank_lines.log
But this didn't work.
I would like to ask what the symbol &&
does and why the above line does not pass the output to the file.
Upvotes: 2
Views: 2502
Reputation: 6809
It's a short-circuited 'and' operator. It takes no part in output redirection.
In this context, it performs the right hand side only if the left hand side succeeded. I.e. it only prints out 'blank line at the ...' if there was indeed a blank line reported by egrep.
Upvotes: 3
Reputation: 125708
The reason the redirect doesn't work is that you used >
to redirect output. This erases the file before writing the command's output to it, meaning that you'll only ever see the last thing written to it. To fix this, either use >>
to append (although you may need to truncate the file at the beginning to prevent the output from multiple runs of the script accumulating), or redirect output for the entire loop.
BTW, the for ... find
construct you're using to iterate over files will fail horribly if any filenames have spaces or other funny characters in them. It's much better to use find ... -print0 | while IFS= read -d $'\0' ...
(and then use double-quotes around $f
):
find . -type f -print0 | while IFS= read -d $'\0' f; do
for t in head tail; do
$t -1 "$f" |egrep '^[ ]*$' >/dev/null && echo "blank line at the $t of $f"
done
done > blank_lines.log
Upvotes: 3
Reputation: 1285
As mentioned by the other guys && is a short-circuited and operator:
command1 && command2
executes command1 and, if that command did run without errors (exit code 0) executes command2. It then returns the exit code of command2.
echo "foo" > /dev/null && echo "bar" > tmp.txt
does work, so the reason your script does not work should be something else. Perhaps try executing the
$t -1 $f |egrep '^[ ]*$' >/dev/null && echo "blank line at the $t of $f" > blank_lines.log
line without the variables and the for loop.
Upvotes: 2
Reputation: 70931
This does not redirect output it adds another command to execute if and only if the first one succeeded. I.e command1 && command2
means execute command1
and if it is successful execute command2
. Also the result of executing this statement is success if and only if both commands succeeded.
Upvotes: 5