# How do I find corrupted archive files?

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?

-

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

find . -iname '*.zip' -type f -readable ! -exec unzip -t {} \; -exec rm -i {} \;

-
Thanks for your answer. a question: what does \! do? –  Omid Nov 12 '12 at 16:00
@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 Nov 12 '12 at 16:02
@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. –  Gilles Nov 12 '12 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 Nov 13 '12 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 Nov 13 '12 at 3:06

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".

-
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 "-". –  Stéphane Chazelas Nov 12 '12 at 15:21
@StephaneChazelas - Good point, added in a read check. –  Chris Down Nov 12 '12 at 15:24