Bash conditionals: how to "and" expressions? (if [ ! -z $VAR && -e $VAR ])
BashShellBash Problem Overview
I guess I'm not clear on how to do "and" tests. I wanted to make sure an argument existed which was working well with [ -e $VAR ]
, but it turns out that was also evaluating as true on an empty string; which I do not want.
How do I 'and' them together? Or is there another unary test that accomplishes what I want?
Bash Solutions
Solution 1 - Bash
if [ ! -z "$var" ] && [ -e "$var" ]; then
# something ...
fi
Solution 2 - Bash
From the bash
manpage:
> [[ expression ]]
- return a status of 0 or 1 depending on the evaluation of the conditional expression expression.
And, for expressions, one of the options is:
> expression1 && expression2
- true if both expression1
and expression2
are true.
So you can and
them together as follows (-n
is the opposite of -z
so we can get rid of the !
):
if [[ -n "$var" && -e "$var" ]] ; then
echo "'$var' is non-empty and the file exists"
fi
However, I don't think it's needed in this case, -e xyzzy
is true if the xyzzy
file exists and can quite easily handle empty strings. If that's what you want then you don't actually need the -z
non-empty check:
pax> VAR=xyzzy
pax> if [[ -e $VAR ]] ; then echo yes ; fi
pax> VAR=/tmp
pax> if [[ -e $VAR ]] ; then echo yes ; fi
yes
In other words, just use:
if [[ -e "$var" ]] ; then
echo "'$var' exists"
fi
Solution 3 - Bash
if [ -n "$var" -a -e "$var" ]; then
do something ...
fi
Solution 4 - Bash
Simply quote your variable:
[ -e "$VAR" ]
This evaluates to [ -e "" ]
if $VAR
is empty.
Your version does not work because it evaluates to [ -e ]
. Now in this case, bash simply checks if the single argument (-e
) is a non-empty string.
From the manpage: > test and [ evaluate conditional expressions using a set of rules based on the number of arguments. ... > > 1 argument > >The expression is true if and only if the argument is not null.
(Also, this solution has the additional benefit of working with filenames containing spaces)
Solution 5 - Bash
I found an answer now. Thanks for your suggestions!
for e in ./*.cutoff.txt; do
if grep -q -E 'COX1|Cu-oxidase' $e
then
echo xyz >$e.match.txt
else
echo
fi
if grep -q -E 'AMO' $e
then
echo abc >$e.match.txt
else
echo
fi; done
Any comments on that? It seems inefficient to grep twice, but it works...