我想在目录中查找文件并通过其 mimetype 进行识别,不是通过文件的扩展名。
我使用此命令来确定 mime 类型:
% 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
第一个文件的文件名中有一个换行符:
% ls foo$'\n'bar.png
foo?bar.png
没关系,文件应该可以不是被重命名。
使用下一个命令,我想过滤所有非图像文件。
% 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
并确定它们的大小:
% 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
但这不起作用,因为没有名为 的文件bar.png
。正确的名字是
./foo
bar.png
名称中带有换行符。
答案1
我认为最好的选择是使用 shell 循环而不是 xargs:然后您可以控制命令如何发送文件名参数。
find . -type f -print0 |
while IFS= read -rd "" filename; do
type=$( file --brief "$filename" )
if [[ $type == *image* ]]; then
identify -format "%[fx:w*h] %i\n" "$filename"
fi
done
答案2
您可以使用该-exec sh -c '...'
构造find
:
find . -type f -exec sh -c 'file --brief --mime-type "$0" | \
grep -q ^image/ && identify -format "%[fx:w*h] %i\n" "$0"' {} \;
或与exiftool
:
exiftool -q -if '$mimetype =~ /image/' -p '$megapixels $directory/$filename' -r .
答案3
正如 Steeldriver 指出的那样,你的问题不是awk
,而是file
。您提供的输入中没有 NULawk
因为file
吃了它。我会在 shell 中完成这一切:
find . -type f -print0 | while IFS= read -r -d '' file; do
file --mime-type "$file" | grep -qP "\bimage/" &&
printf '%s %s\0' $(identify -format '%[fx:w*h]' "$file") "$file";
done | sort -gz | tr '\0' '\n'
256 ./file 10
256 ./file 15
484 ./file 16
576 ./file 11
576 ./file 17
1024 ./file 12
1024 ./file 19
2304 ./file 13
5625 ./file 14
15190 ./file 2
15680 ./file 1
16384 ./file 9
65536 ./file 18
145200 ./file 0
183531 ./file 6
364807 ./file
3
364807 ./file 4
364807 ./file 5
388245 ./file 8
550560 ./file 7
我加入是sort
因为我假设您正在尝试改进您的答案这里。上面的示例是在带有空格和一个(file\n3
带有换行符)的文件名上运行的。由于某种原因,identify
不会打印\0
- 终止的行,所以我用它来printf
代替。