Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm trying to write a bash script that will go into a directory loop through the .gz files and delete them if they are empty (ie the uncompressed file contained within in empty.

I've got a couple of questions:

  • Is there a standard file size of a compressed (gz) empty file I can check for?
  • Or is there a better way to check if a gz contains an empty file without decompressing it with a bash script?

I was trying to use the following code to acheive this but it relies on the filesize being 0 i think.

for f in dir/*
do
    if [[ -s $f ]]
    then
        do_file_creation
    fi
done
share|improve this question
    
I'm not sure about this , if the gzipped file is empty , is the size also empty ? –  warl0ck Jun 1 '12 at 5:33
add comment

5 Answers

up vote 6 down vote accepted

Unfortunately the gzip contains the orginal filename, so the its size will vary without for different empty files.

gunzip -c $f | head -c1 | wc -c

will echo 1 for files that are non-zero in uncompressed size, and 0 for compressed empty files.

for f in dir/*
do
    if [[ $(gunzip -c $f | head -c1 | wc -c) == "0" ]] 
    then
        do_file_creation
    fi
done

Might do what you want?

share|improve this answer
    
This is the correct approach, since the use of head avoids completely decompressing giant gzip files just to find out if they have one or more bytes. If there really are zero uncompressed bytes in the file, then it will complete very quickly. Using gunzip -l is not guaranteed to work, since you can have multiple gzip streams in a file, and gzip -l will only tell you about the last one. Also a gzip file with an exact multiple of 4 GB of uncompressed data will show up as zero length to gzip -l. –  Mark Adler May 29 '12 at 22:01
add comment

You could add -l to gzip|gunzip|zcat to print out information about the gzipped file and then test against the uncompressed file size.

$ gunzip -l file.empty.gz 
compressed        uncompressed  ratio uncompressed_name
        31                   0   0.0% file.empty
share|improve this answer
add comment

The filename (or the absence of the filename within the compressed file) will change the size of the files so you can't look for a standard size, e.g.

$ touch file1 file2-longer-name file3
$ gzip file1 file2-longer-name
$ gzip --no-name file3
$ ls -l file*.gz
-rw-r--r-- 1 cwarden cwarden 26 May 29 10:33 file1.gz
-rw-r--r-- 1 cwarden cwarden 38 May 29 10:33 file2-longer-name.gz
-rw-r--r-- 1 cwarden cwarden 20 May 29 10:33 file3.gz

I would probably do something like this:

for f in dir/*; do
    zcat $f | head -1 | ifne -n rm -f $f > /dev/null
done
share|improve this answer
add comment

There is probably a better way but this should give you the file size of the uncompressed version of the compressed file:

export fsize=$(gunzip -l ${f} | tail -1 | awk -F " " '{print $2}' )

share|improve this answer
add comment
for i in *.gz
do
     [ `zcat "$i" | head -n 1 | wc -c ` -eq 0 ] && rm -i "$i"
done

The zcat "$i" | head -n 1 | wc -c will count the number of characters in the first line of the file, this avoids uncompressing the whole file by just looking at the beginning of it.

I also added a -i to the rm command to ask for confirmation before deleting the file, but you could remove that if it's unecessary in your case.

share|improve this answer
3  
Don't do for x in $(ls ...), just use for x in *.gz. It's more whitespace-safe and more readable. –  Kevin May 29 '12 at 17:45
    
@Kevin, neither is whitespace-safe. Use IFS=$(echo -e "\n\r"); for i in $(ls -1 *gz); do.... –  xn. May 29 '12 at 17:55
1  
@xn. incorrect, the glob in for x in *.gz is a standard glob, it's perfectly whitespace-safe. Yours, on the other hand, won't handle filenames with \n\r in the name. –  Kevin May 29 '12 at 18:01
    
P.S. Better to use $'\n\r' instead of $(echo -e "\n\r"). –  Kevin May 29 '12 at 18:03
    
@Kevin: didn't know about the $'\n\r' syntax. Thanks. Without changing IFS, how do you avoid having to quote $i? bit.ly/LCg1C6 –  xn. May 29 '12 at 18:08
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.