使用find命令列出所有的图形图像文件?

61

这个庞大的存档中有许多种类的图形图像,如.jpg、.gif、.png等,我不知道所有的类型。有没有一种方法能够使用“查找”列表出所有图形图像,而不考虑它们的扩展名呢?谢谢!


1
很抱歉,您需要编写一个调用所有扩展名的查找命令的Bash脚本。 - Mr Lister
它是否可以与知道文件类型的“file”命令相结合? - Edward
对于_视频_,请参阅此处的相应问答:Ask Ubuntu: 如何在我的系统上找到所有视频文件?。对于想要添加新答案的任何人来说,您可能也可以直接在那里添加。 - Gabriel Staples
6个回答

73
这应该能解决问题。
find . -name '*' -exec file {} \; | grep -o -P '^.+: \w+ image'

示例输出:

./navigation/doc/Sphärische_Trigonometrie-Dateien/bfc9bd9372f650fd158992cf5948debe.png: PNG image
./navigation/doc/Sphärische_Trigonometrie-Dateien/6564ce3c5b95ded313b84fa918b32776.png: PNG image
./navigation/doc/subr_1.jpe: JPEG image
./navigation/doc/Astroanalytisch-Dateien/Gamma.gif: GIF image
./navigation/doc/Astroanalytisch-Dateien/deltaS.jpg: JPEG image
./navigation/doc/Astroanalytisch-Dateien/GammaBau.jpg: JPEG image

2
是否有类似的方法可以用于视频呢?似乎将“图像”替换为“视频”会跳过快速时间和Matroska格式... - Elder Geek
1
@ElderGeek 我会在一些示例上运行file命令,看看有没有可以用grep搜索的文本片段。在awk解决方案的图像部分,你可以使用替代符号分隔模式,例如/video|image|foo/ 将返回其描述中包含单词"video"、"image"或"foo"的所有文件。 - f3xy
@SaulOrtega 那就是我下面发布的答案。 - f3xy
1
请注意,\w+ 部分将排除类似 foo.svg: SVG 可缩放矢量图形 的结果。要查找例如 .svg 文件,请将 \w+ 更改为 .* - Løiten
1
对于macOS mojave,grep没有-P选项,并且file命令的输出非常冗长。顺便说一下,如果您能解释一下您的命令,那就更好了。 - DawnSong
显示剩余4条评论

44

以下更适合我,因为在我的情况下,我想将这个文件列表传输到另一个程序中。

find . -type f -exec file --mime-type {} \+ | awk -F: '{if ($2 ~/image\//) print $1}'

如果你想把这些图��打包成tar文件(正如评论中有人提到的那样)
find . -type f -exec file --mime-type {} \+ | awk -F: '{if ($2 ~/image\//) printf("%s%c", $1, 0)}' | tar -cvf /tmp/file.tar --null -T -

第一行代码利用了以下命令:findfileawk。第二行代码加入了tar。最好的方法是查阅本地手册,了解您特定系统的行为。


2
如果您想将输出导入管道中,这确实是默认答案。谢谢! - Paulo Fidalgo
你怎么样将这些文件传递到 tarzip 中呢? - khaverim
1
@khaverim,我已更新我的答案,应该可以解决问题。 - f3xy
请注意,此命令无法处理包含 : 的文件名,请考虑以下三种解决方案:
  1. find . -type f -exec file --mime-type {} \+ | rev | awk -F: '{ st = index($0, ":"); if (substr($0, 1, st) ~/\/egami/) print substr($0, st+1) }' | rev
  2. find . -type f -exec file --mime-type {} \+ | awk -F: -vOFS=: '{if ($NF ~/image\//) {$NF=""; print $0} }' | sed 's/:$//'.
- 林果皞
继续。3. find . -type f -exec file --mime-type {} \+ | awk '{ n=split($0, Arr, ":"); for (i=0; i<n; i++) { if ($NF ~/image\//) { if(i == n-1) { print Arr[i] } else if(i == 0) { printf "%s", Arr[i]} else { printf "%s", Arr[i] ":" } } } }' - 林果皞
显示剩余8条评论

13
find . -type f -exec file {} \; | grep -o -P '^.+: \w+ image'

应该变得更好。


3
为什么这个更好? - Selah
file 命令已更改,因此在 macOS Mojave 上无法正常工作。 - DawnSong
2
@DawnSong 注意,该问题是关于Linux的。 - naXa stands with Ukraine
1
@Selah 这个命令指定了 -type f,它会获取文件而不是文件夹,并执行 file 命令,因此可能比 j.holetzeck 的答案快一些。 - liginity
1
如果文件名匹配 ^.+: \w+ image,例如 hello: fake image,则此命令存在问题。考虑使用以下解决方案:find . -type f -print0 | xargs -0 bash -c 'for arg do file -b --mime-type "$arg" | grep -q '^image/' && echo "$arg"; done' _。解释:1. file -b 仅输出文件类型以避免文件名匹配 ^.+: \w+ image。2. -print0 | xargs -0 能够处理文件名中的换行符,而我的其他注释无法处理这种奇特情况。3. for 循环带有尾随 _,以覆盖文件名中的 '$var。4. --mime-type 避免了 .psd("I"mage)和 .eps(没有 "image")文件类型问题。 - 林果皞

8

仅使用grep或awk查找“image”是不够的。PSD文件将通过大写字母“I”的“Image”进行识别,因此我们需要改进正则表达式,使其不区分大小写或包括大写字母I。EPS文件根本不包含单词“image”,因此我们还需要匹配“EPS”或“Postscript”,具体取决于您想要的内容。因此,这是我的改进版本:

find . -type f -exec file {} \; | awk -F: '{ if ($2 ~/[Ii]mage|EPS/) print $1}'

3

更新(2022年03月03日)

这是一个经过改进的版本,具有以下更改:

  1. 移除了 xargs
  2. 根据林果皞的评论,支持文件名包含 :
find . -type f |
  file --mime-type -f - |
  grep -F image/ |
  rev | cut -d : -f 2- | rev

以下是比所选答案更高效的解决方案:

find . -type f -print0 |
  xargs -0 file --mime-type |
  grep -F 'image/' |
  cut -d ':' -f 1
  1. 使用-type f代替-name '*',因为前者只会搜索文件,而后者搜索文件和目录。
  2. xargs尽可能地执行file的参数,这比find -exec file {} \;执行对于每个找到的文件都执行file要快得多。
  3. grep -F更快,因为我们只想匹配固定的字符串。
  4. cutawk更快(我记得是超过5倍)。

1
根据我的有限测试,我的更新调用比您目前拥有的更快,但我欢迎评论。您使用xargs让我想起find执行了相同的操作。另外,find的mime-types选项是一个很好的补充。它产生的结果与之前不同,但最大的优点是它排除了虚拟机映像。为了准确比较awk,您需要将grep与cut组合在一起使用,因为这两个命令都在执行。尽管如此,awk会为您提供更多的灵活性。谢谢。 - f3xy
应该将 cut -d ':' -f 1 改为 rev | cut -d ':' -f 2- | rev,以打印包含 : 的完整文件名。例如 hello : world.jpg - 林果皞

1

与同一问题相关,我刚刚发布了一个名为photofindhttps://github.com/trimap/photofind)的工具。它的行为类似于普通的find命令,但专门用于图像文件,并支持基于图像文件中存储的EXIF信息过滤结果。请参阅链接的github存储库以获取更多详细信息。


3
这个工具似乎依赖于文件名以文件扩展名结尾,但这种方法远不如检查文件命令的输出稳健。你提供的链接中有一个find命令的示例(find ~/Pictures \( -iname "*.jpg" -or -iname "*.jpeg" -or -iname "*.png" -or -iname "*.tif" -or -iname "*.bmp" -or -iname "*.gif" -or -iname"*.xpm" -or -iname "*.nef" -or -iname "*.cr2" -or -iname "*.arw" \) -size +20k)。 - f3xy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接