Wanted to check if there are multiple files with the same prefix exist in that directory.

here directory --> WORK_DIR and file prefix -->SRC_FILE_EXT

i currently have the script like this:

if [ -s ${WORK_DIR}${SRC_FILE_EXT} ] ;  then
   echo "+ File is present on the source directory" >> $LOG_FILE

   echo "No files to move" >> $LOG_FILE
   exit 4

But this script throws No files to move..

Could someone help me out here

  • 1
    (1) Your code does not check if file exists, but if file is not empty, use -f if you want to check for regular file exists. (2) The word "multiple" confuses me, as this is not part of your script. (3) Always quote paths/filenames!! Use "${WORK_DIR}${SRC_FILE_EXT}" and "$LOG_FILE". (4) For debugging, make sure that WORK_DIR and SRC_FILE_EXT are correctly set when running if. And that you have a / in between. (5) For more debugging, use set -x to print out what is actually executed.
    – pLumo
    Commented Jul 12, 2019 at 8:30

2 Answers 2

shopt -s nullglob


printf 'There are %d names that match "%s"\n' "$#" "$WORK_DIR/$SRC_FILE_EXT*"

That is, expand the pattern that matches the names that you are interested in, setting the positional parameters. The special variable $# will contain the number of matched names. Set the nullglob shell option in bash to let the pattern expand to nothing if it does not match at all.

If you want to make sure that you don't match directories, you may use a simple loop that counts the non-directories:

shopt -s nullglob

for name in "$WORK_DIR/$SRC_FILE_EXT"*; do
    [ ! -d "$name" ] && num=$(( num + 1 ))

printf 'There are %d non-directories with names that match "%s"\n' "$num" "$WORK_DIR/$SRC_FILE_EXT*"

Using find:

find "$WORK_DIR" -maxdepth 1 ! -type d -name "$SRC_FILE_EXT*" -exec echo x \; | wc -l

(assuming your find knows about the non-standard -maxdepth predicate). This would return the number of non-directories in $WORK_DIR whose names start with $SRC_FILE_EXT.

num=$( find "$WORK_DIR" -maxdepth 1 ! -type d -name "$SRC_FILE_EXT*" -exec echo x \; | wc -l )

printf 'There are %d non-directories with names that match "%s" in "%s"\n' \
    "$num" "$SRC_FILE_EXT*" "$WORK_DIR"

There is a subtle difference between using shell globs to match names and using find in that find is more strict with its file type matching. The find utility will not detect a symbolic link to a file or a directory as a file or directory, but as a symbolic link, while the shell will dereference the symbolic link and test the thing that it links to.


As you are talking of "files" in plural and a prefix, I suppose that the filenames contain $SRC_FILE_EXT with something after it, so you'd need a globbing pattern like $SRC_FILE_EXT*.

But this could give you multiple matches, while test -s takes only one argument.

So I suggest to modify your test to

if [ "$(find . -name \"${WORK_DIR}/${SRC_FILE_EXT}*\" )" != "" ]; then
  • Escaping the double quotes in the argument to -name would make find look for files with literal double quotes in their names. Also, the -name predicate will never be true for a pattern that contains a /. You may test for a non-empty string with the -n test.
    – Kusalananda
    Commented Jul 12, 2019 at 10:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .