5

I have a lot of zip files. Some are not downloaded correctly and are corrupted. I want to remove them.

Is there a way to find the corrupted archives in bash?

3 Answers 3

7

With GNU (for -readable and -iname) find:

find . -iname '*.zip' -type f -readable ! -exec unzip -t {} \; -exec rm -i {} \;
6
  • Thanks for your answer. a question: what does \! do?
    – Omid
    Commented Nov 12, 2012 at 16:00
  • 1
    @Nima It's a logical not operator, ie. if unzip -t {} fails, exec rm -i {}. It has to be escaped because by default ! is used for history expansion in bash.
    – Chris Down
    Commented Nov 12, 2012 at 16:02
  • 2
    @ChrisDown Is there actually a shell that doesn't treat ! literally when it's followed by a space? I have the habit of writing \! too, but I thought it was out of habit (because ! has to be quoted in so many places in bash), not out of necessity. Commented Nov 12, 2012 at 23:35
  • @Gilles - Good point! I don't know of any. I guess this goes also to the manual pages saying that {} needs escaping...
    – Chris Down
    Commented Nov 13, 2012 at 2:21
  • maybe @Nima wants to remove the files manualy then using -print0 instead of exec rm -i {} \; will display the files that are corrupted without deleting them.
    – miracle173
    Commented Nov 13, 2012 at 3:06
2

The following will print the name of all corrupted zip files in the current directory and its subdirectories:

#!/bin/bash
shopt -s dotglob nullglob globstar
for file in ./**/*.zip; do
    [[ -r $file ]] || continue
    unzip -t "$file" >/dev/null 2>&1 || printf '%s\n' "$file"
done

If you wish to remove them, simply replace printf '%s\n' "$file" with rm -f "$file".

2
  • 1
    Beware though that it's not the same permissions that apply to read a file and to delete it, so you may end up deleting a file just because you don't have the right to read it. Also note that bash recursive globbing (contrary to other shells) descends into symlinks to directories which is generally not what you want. Also, you may want to write it ./**/*.zip to avoid problems with file/dir names starting with "-". Commented Nov 12, 2012 at 15:21
  • @StephaneChazelas - Good point, added in a read check.
    – Chris Down
    Commented Nov 12, 2012 at 15:24
0

To find the corrupted archives in bash, I use the following script:

#!/bin/bash

# change myfolder value below fully
myfolder="/Users/nathan/Downloads/some folder"

cd "$myfolder"

rm -f testlog.sh
rm -f testlog.txt

SQ="'"

find . -type f -iname '*.zip' -print | while read line
do
echo "unzip -t ${SQ}${line}${SQ}" | tee -a testlog.sh 2>&1;
done

bash testlog.sh | tee -a testlog.txt 2>&1;

totalcommands=$(wc -l testlog.sh|awk '{print $1}')
totalstatus=$(grep -o "No errors detected in compressed data of " testlog.txt | grep -c "")

echo
if [ $totalcommands -eq $totalstatus ]; then
echo "-------------------------------"
echo "All Tests Returned Success !!!!"
echo "-------------------------------"
else
echo "---------------------------------------------------------------------------"
echo "Some Tests Failed. Please check the ${SQ}${myfolder}/testlog.txt${SQ} file."
echo "---------------------------------------------------------------------------"
fi
echo

Hope this helps.

You must log in to answer this question.

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