-
Notifications
You must be signed in to change notification settings - Fork 33
/
mimefind.pl
93 lines (71 loc) · 1.96 KB
/
mimefind.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/perl
# Author: Trizen
# Date: 17 April 2023
# Edit: 21 September 2023
# https://github.com/trizen
# Find files from a given directory (and its subdirectories) that have a specific mimetype.
use 5.036;
use File::Find qw(find);
use Getopt::Std qw(getopts);
sub usage ($exit_code = 0) {
print <<"EOT";
usage: $0 [options] [files | dirs]
options:
-T : display only text files
-B : display only binary files
-t TYPE : display files with this mimetype (regex)
-n : display non-matching files
-f : display only files
-e : use `exiftool` to determine the MIME types (slow)
-h : display this message and exit
examples:
perl $0 -t video ~/Music # find video files
perl $0 -Bft . ~/Documents # find binary files
perl $0 -fn -t audio ~/Music # find non-audio files
perl $0 -fn -t 'audio|video' ~/Music # find non audio/video files
EOT
exit($exit_code);
}
getopts('TBefhnt:', \my %opts);
$opts{t} || usage(1);
$opts{h} && usage(0);
my $type_re = qr/$opts{t}/i;
sub determine_mime_type ($file) {
if (-d $file) {
return 'inode/directory';
}
if ($opts{e}) {
my $res = `exiftool \Q$file\E`;
$? == 0 or return;
defined($res) or return;
if ($res =~ m{^MIME\s+Type\s*:\s*(\S+)}mi) {
return $1;
}
return;
}
require File::MimeInfo::Magic;
File::MimeInfo::Magic::mimetype($file);
}
find(
{
wanted => sub {
if ($opts{f}) {
(-f $_) or return;
}
if ($opts{B}) {
(-B $_) or return;
}
if ($opts{T}) {
(-T $_) or return;
}
my $mimetype = determine_mime_type($_) // return;
my $ok = ($mimetype =~ $type_re);
$ok = !$ok if $opts{n};
if ($ok) {
say $File::Find::name;
}
},
no_chdir => 1,
},
@ARGV
);