Shell – awk and newlines in the input data

awkshell

I want to find files in a directory and identify by their mimetype, not by the extension of the files.

I'am using this command to determine the mime type:

% find . -type f -print0 | xargs -0 -I{} file --mime-type {}
./foo
bar.png: image/png
./OWoHp.png: image/png
./J7ZwV.png: image/png
./foo.txt: inode/x-empty
./bar: inode/x-empty
./hUXnc.png: image/png

The first file has a newline in the filename:

% ls foo$'\n'bar.png
foo?bar.png

That's ok and the file should not be renamed.

With the next command I want to filter all files that are not images.

% find . -type f -print0 | xargs -0 -I{} file --mime-type {} | awk -F$"\0" -F": " '/image/ {print $1}'
bar.png
./OWoHp.png
./J7ZwV.png
./hUXnc.png

and identify their sizes:

% find . -type f -print0 | xargs -0 -I{} file --mime-type {} | awk -F$"\0" -F":" '/image/ {print $1}' | xargs -I{} identify -format "%[fx:w*h] %i\n" {}
identify: unable to open image `bar.png': No such file or directory @ error/blob.c/OpenBlob/2709.
identify: unable to open file `bar.png' @ error/png.c/ReadPNGImage/3922.
26696 ./OWoHp.png
47275 ./J7ZwV.png
37975 ./hUXnc.png

But that does not work because there is no file with the name bar.png. The correct name is

./foo
bar.png

with a newline in the name.

Best Answer

You could use the -exec sh -c '...' construct with find:

find . -type f -exec sh -c 'file --brief --mime-type "$0" | \
grep -q ^image/ && identify -format "%[fx:w*h] %i\n" "$0"' {} \;

or with exiftool:

exiftool -q -if '$mimetype =~ /image/' -p '$megapixels $directory/$filename' -r .
Related Question