Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

After fsck'ing an ext4 drive that had been running in a QNAP nas without an fsck for about four years, I now have a number of files that seem but be the correct size (typically 8-12mib), but each byte of their contents is null/NUL/00 (i.e. 0 repeated over and over again when seen in a hex editor).

I've checked this with the 'hexedit' tool as well as sampling various lengths of bytes with 'od'

Rather than search amongst 10,000+ NEF and JPEG image files, is there a way I might be able to automate the search these files and write them to a list - so I can restore them from a backup?

share|improve this question

2 Answers 2

Assuming your files contain ONLY the NULL string (no new line, \n), you can use grep and find to locate these files.

The find command will collect all files that are at least 1 byte in size (-size +1c) in the current directory and then use grep to check if they contain only repetitions of the NULL character:

$ find . -type f -size +1c -exec grep -m 1 -ovP "[^\0]" {} \; 
Binary file ./empty_file with spaces.jpg matches
Binary file ./empty_file matches

The -v flag of grep causes it to print non matching lines. -m 1 means "Stop after the first match", -o means print only the part of the line that matches (avoids printing empty lines from other files) and P uses Perl regular expressions. The pattern [^\0], means any non NULL character. By reversing this (-v) and adding the -m 1 flag, grep will report a match only if the file contains nothing but NULL.

Finally, you can pipe this through cut and sed to print the name of the matching file alone:

$ find . -type f -size +1c -exec grep -m 1 -ovP "[^\0]" {} \; | cut -d ' ' -f 3- | sed 's/ matches//'
./empty_file with spaces.jpg
./empty_file
share|improve this answer
    
Excellent, thanks! –  inflammable Feb 13 '13 at 8:32
1  
I couldn't seem to get the grep options '-ov' to get me the result you describe above, however this worked: 'find . -type f -size +1c -exec grep -m 1 -LP "[^\0]" {} \;' though I'm not sure it's exactly equivalent. –  inflammable Feb 13 '13 at 10:03

Though the above answer is much more thorough (and less convoluted) in its inspection of the files, cobbled together the following. There are a few extra commands just to deal with the odd way in which the NAS handles filenames, but it uses 'od' to get the first 32 bytes of the file (my rationale was that if the first 32 bytes are null, then the rest are likely to be too, especially for images):

find "$(pwd)" -type f -exec sh -c 'file=$(echo "{}" | sed "s/([\(\)])/\\\1/g"); check=$(od -N32 -w32 -x "$file"); if echo $check | grep --quiet " 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000"; then echo "$file" $check; fi' \;

I tried this on a subset of the folders I suspect are corrupted and I saved the results out to a file. After checking each file by hand I was pretty happy that it was reliable.

share|improve this answer

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.