madhav g
madhav g

Reputation: 83

Check if multiple files are empty in single if statement

awkOut1="awkOut1.csv"
awkOut2="awkOut2.csv"
if [[ "$(-s $awkOut1)" || "$(-s $awkOut2)" ]]

The above 'if' check in shell script gives me below error:

-bash: -s: command not found

Suggestions anyone?

Upvotes: 1

Views: 2483

Answers (3)

Rob Davis
Rob Davis

Reputation: 15772

You can use basic Bourne shell syntax and the test command (a single left bracket) to find out if either file is non-empty:

if [ -s "$awkOut1" -o -s "$awkOut2" ]; then
  echo "One of the files is non-empty."
fi

When using single brackets, the -o means "or", so this expression is checking to see if awkOut1 or awkOut2 is non-empty.


If you have a whole directory full of files and you want to find out if any of them is empty, you could do something like this (again with basic Bourne syntax and standard utilities):

find . -empty | grep -q . && echo "some are empty" || echo "no file is empty"

In this line, find will print any files in the current directory (and recursively in any subdirectories) that are empty; grep will turn that into an exit status; and then you can take action based on success or failure to find empties. In an if statement, it would look like this:

if find . -empty | grep -q .; then
  echo "some are empty"
else
  echo "no file is empty"
fi

Upvotes: 1

James Brown
James Brown

Reputation: 37414

Here is one for GNU awk and filefuncs extension. It checks all parameter given files and exits once the first one is empty:

$ touch foo
$ awk '
@load "filefuncs"                                  # enable
END {
    for(i=1;i<ARGC;i++) {                          # all given files 
        if(stat(ARGV[i], fdata)<0) {               # use stat 
            printf("could not stat %s: %s\n",      # nonexists n exits
                   ARGV[i], ERRNO) > "/dev/stderr"
            exit 1
        }
        if(fdata["size"]==0) {                     # file size check
            printf("%s is empty\n", 
                   ARGV[i]) > "/dev/stderr"
            exit 2
        }
    }
    exit
}' foo

Output:

foo is empty

Upvotes: 0

glenn jackman
glenn jackman

Reputation: 246867

If you just have 2 files I would do

if [[ -e "$awkOut1" && ! -s "$awkOut1" ]] &&
   [[ -e "$awkOut2" && ! -s "$awkOut2" ]]
then
    echo both files exist and are empty
fi

Since [[ is a command, you can chain the exit statuses together with && to ensure they are all true. Also, within [[ (but not [), you can use && to chain tests together.

Note that -s tests for True if file exists and is not empty. so I'm explicitly adding the -e tests so that -s only checks if the file is not empty.

If you have more than 2:

files=( awkOut1.csv awkOut2.csv ... )
sum=$( stat -c '%s' "${files[@]}" | awk '{sum += $1} END {print sum}' )
if (( sum == 0 )); then
    echo all the files are empty
fi

This one does not test for existence of the files.

Upvotes: 2

Related Questions