Reputation: 2315
How can I use the test
command for an arbitrary number of files, passed in using an argument with a wildcard?
For example:
test -f /var/log/apache2/access.log.* && echo "exists one or more files"
Currently, it prints
error: bash: test: too many arguments
Upvotes: 31
Views: 92361
Reputation: 1
Faced the same issue and I put together one-liner using test, without error if no such file exists:
[ $(ls /var/log/apache2/access.log.* 2>/dev/null | wc -l) -gt 0 ] && echo "exists one or more files" || echo "no log files"
Upvotes: 0
Reputation: 867
This condition below doesn't produce stderr. the condition's blackhole (/dev/null) doesn't prevent the stderr in cmd.
if [[ $(ls -1 /var/log/apache2/access.log.* | wc -l ) -gt 0 ]] 2> /dev/null
therefore I suggests this code.
if [[ $(ls -1 /var/log/apache2/access.log.* | wc -l ) -gt 0 ]] 2> /dev/null
then
echo "exists one or more files."
fi
Upvotes: 1
Reputation: 10222
To avoid "too many arguments error", you need xargs
. Unfortunately, test -f
doesn't support multiple files. The following one-liner should work:
for i in /var/log/apache2/access.log.*; do test -f "$i" && echo "exists one or more files" && break; done
By the way, /var/log/apache2/access.log.*
is called shell-globbing, not regexp. Please see Confusion with shell-globbing wildcards and Regex for more information.
Upvotes: 12
Reputation: 1832
more simplyfied:
if ls /var/log/apache2/access.log.* 2>/dev/null 1>&2; then
echo "ok"
else
echo "ko"
fi
Upvotes: 0
Reputation: 106
This one is suitable for use with the Unofficial Bash Strict Mode, no has non-zero exit status when no files are found.
The array logfiles=(/var/log/apache2/access.log.*)
will always contain at least the unexpanded glob, so one can simply test for existence of the first element:
logfiles=(/var/log/apache2/access.log.*)
if [[ -f ${logfiles[0]} ]]
then
echo 'At least one file found'
else
echo 'No file found'
fi
Upvotes: 6
Reputation: 581
Or using find
if [ $(find /var/log/apache2/ -type f -name "access.log.*" | wc -l) -gt 0 ]; then
echo "ok"
else
echo "ko"
fi
Upvotes: 1
Reputation: 111
First, store files in the directory as an array:
logfiles=(/var/log/apache2/access.log.*)
Then perform a test on the count of the array:
if [[ ${#logfiles[@]} -gt 0 ]]; then
echo 'At least one file found'
fi
Upvotes: 11
Reputation: 236
Variation on a theme:
if ls /var/log/apache2/access.log.* >/dev/null 2>&1
then
echo 'At least one file found'
else
echo 'No file found'
fi
Upvotes: 2
Reputation: 561
This solution seems to me more intuitive:
if [ `ls -1 /var/log/apache2/access.log.* 2>/dev/null | wc -l ` -gt 0 ];
then
echo "ok"
else
echo "ko"
fi
Upvotes: 56
Reputation: 81
You just need to test if ls
has something to list:
ls /var/log/apache2/access.log.* >/dev/null 2>&1 && echo "exists one or more files"
Upvotes: 3
Reputation: 361
ls -1 /var/log/apache2/access.log.* | grep . && echo "One or more files exist."
Upvotes: 1
Reputation: 1482
If you wanted a list of files to process as a batch, as opposed to doing a separate action for each file, you could use find, store the results in a variable, and then check if the variable was not empty. For example, I use the following to compile all the .java files in a source directory.
SRC=`find src -name "*.java"`
if [ ! -z $SRC ]; then
javac -classpath $CLASSPATH -d obj $SRC
# stop if compilation fails
if [ $? != 0 ]; then exit; fi
fi
Upvotes: 5