1File::GlobMapper(3) User Contributed Perl Documentation File::GlobMapper(3)
2
3
4
6 File::GlobMapper - Extend File Glob to Allow Input and Output Files
7
9 use File::GlobMapper qw( globmap );
10
11 my $aref = globmap $input => $output
12 or die $File::GlobMapper::Error ;
13
14 my $gm = new File::GlobMapper $input => $output
15 or die $File::GlobMapper::Error ;
16
18 WARNING Alpha Release Alert!
19
20 * This code is a work in progress.
21 * There are known bugs.
22 * The interface defined here is tentative.
23 * There are portability issues.
24 * Do not use in production code.
25 * Consider yourself warned!
26
27 This module needs Perl5.005 or better.
28
29 This module takes the existing "File::Glob" module as a starting point
30 and extends it to allow new filenames to be derived from the files
31 matched by "File::Glob".
32
33 This can be useful when carrying out batch operations on multiple files
34 that have both an input filename and output filename and the output
35 file can be derived from the input filename. Examples of operations
36 where this can be useful include, file renaming, file copying and file
37 compression.
38
39 Behind The Scenes
40
41 To help explain what "File::GlobMapper" does, consider what code you
42 would write if you wanted to rename all files in the current directory
43 that ended in ".tar.gz" to ".tgz". So say these files are in the cur‐
44 rent directory
45
46 alpha.tar.gz
47 beta.tar.gz
48 gamma.tar.gz
49
50 and they need renamed to this
51
52 alpha.tgz
53 beta.tgz
54 gamma.tgz
55
56 Below is a possible implementation of a script to carry out the rename
57 (error cases have been omitted)
58
59 foreach my $old ( glob "*.tar.gz" )
60 {
61 my $new = $old;
62 $new =~ s#(.*)\.tar\.gz$#$1.tgz# ;
63
64 rename $old => $new
65 or die "Cannot rename '$old' to '$new': $!\n;
66 }
67
68 Notice that a file glob pattern "*.tar.gz" was used to match the
69 ".tar.gz" files, then a fairly similar regular expression was used in
70 the substitute to allow the new filename to be created.
71
72 Given that the file glob is just a cut-down regular expression and that
73 it has already done a lot of the hard work in pattern matching the
74 filenames, wouldn't it be handy to be able to use the patterns in the
75 fileglob to drive the new filename?
76
77 Well, that's exactly what "File::GlobMapper" does.
78
79 Here is same snippet of code rewritten using "globmap"
80
81 for my $pair (globmap '<*.tar.gz>' => '<#1.tgz>' )
82 {
83 my ($from, $to) = @$pair;
84 rename $from => $to
85 or die "Cannot rename '$old' to '$new': $!\n;
86 }
87
88 So how does it work?
89
90 Behind the scenes the "globmap" function does a combination of a file
91 glob to match existing filenames followed by a substitute to create the
92 new filenames.
93
94 Notice how both parameters to "globmap" are strings that are delimited
95 by <>. This is done to make them look more like file globs - it is
96 just syntactic sugar, but it can be handy when you want the strings to
97 be visually distinctive. The enclosing <> are optional, so you don't
98 have to use them - in fact the first thing globmap will do is remove
99 these delimiters if they are present.
100
101 The first parameter to "globmap", "*.tar.gz", is an Input File Glob.
102 Once the enclosing "< ... >" is removed, this is passed (more or less)
103 unchanged to "File::Glob" to carry out a file match.
104
105 Next the fileglob "*.tar.gz" is transformed behind the scenes into a
106 full Perl regular expression, with the additional step of wrapping each
107 transformed wildcard metacharacter sequence in parenthesis.
108
109 In this case the input fileglob "*.tar.gz" will be transformed into
110 this Perl regular expression
111
112 ([^/]*)\.tar\.gz
113
114 Wrapping with parenthesis allows the wildcard parts of the Input File
115 Glob to be referenced by the second parameter to "globmap", "#1.tgz",
116 the Output File Glob. This parameter operates just like the replacement
117 part of a substitute command. The difference is that the "#1" syntax is
118 used to reference sub-patterns matched in the input fileglob, rather
119 than the $1 syntax that is used with perl regular expressions. In this
120 case "#1" is used to refer to the text matched by the "*" in the Input
121 File Glob. This makes it easier to use this module where the parameters
122 to "globmap" are typed at the command line.
123
124 The final step involves passing each filename matched by the "*.tar.gz"
125 file glob through the derived Perl regular expression in turn and
126 expanding the output fileglob using it.
127
128 The end result of all this is a list of pairs of filenames. By default
129 that is what is returned by "globmap". In this example the data struc‐
130 ture returned will look like this
131
132 ( ['alpha.tar.gz' => 'alpha.tgz'],
133 ['beta.tar.gz' => 'beta.tgz' ],
134 ['gamma.tar.gz' => 'gamma.tgz']
135 )
136
137 Each pair is an array reference with two elements - namely the from
138 filename, that "File::Glob" has matched, and a to filename that is
139 derived from the from filename.
140
141 Limitations
142
143 "File::GlobMapper" has been kept simple deliberately, so it isn't
144 intended to solve all filename mapping operations. Under the hood
145 "File::Glob" (or for older versions of Perl, "File::BSDGlob") is used
146 to match the files, so you will never have the flexibility of full Perl
147 regular expression.
148
149 Input File Glob
150
151 The syntax for an Input FileGlob is identical to "File::Glob", except
152 for the following
153
154 1. No nested {}
155
156 2. Whitespace does not delimit fileglobs.
157
158 3. The use of parenthesis can be used to capture parts of the input
159 filename.
160
161 4. If an Input glob matches the same file more than once, only the
162 first will be used.
163
164 The syntax
165
166 ~
167 ~user
168 . Matches a literal '.'. Equivalent to the Perl regular expression
169
170 \.
171
172 * Matches zero or more characters, except '/'. Equivalent to the
173 Perl regular expression
174
175 [^/]*
176
177 ? Matches zero or one character, except '/'. Equivalent to the Perl
178 regular expression
179
180 [^/]?
181
182 \ Backslash is used, as usual, to escape the next character.
183
184 [] Character class.
185
186 {,} Alternation
187
188 () Capturing parenthesis that work just like perl
189
190 Any other character it taken literally.
191
192 Output File Glob
193
194 The Output File Glob is a normal string, with 2 glob-like features.
195
196 The first is the '*' metacharacter. This will be replaced by the com‐
197 plete filename matched by the input file glob. So
198
199 *.c *.Z
200
201 The second is
202
203 Output FileGlobs take the
204
205 "*" The "*" character will be replaced with the complete input file‐
206 name.
207
208 #1 Patterns of the form /#\d/ will be replaced with the
209
210 Returned Data
211
213 A Rename script
214
215 Below is a simple "rename" script that uses "globmap" to determine the
216 source and destination filenames.
217
218 use File::GlobMapper qw(globmap) ;
219 use File::Copy;
220
221 die "rename: Usage rename 'from' 'to'\n"
222 unless @ARGV == 2 ;
223
224 my $fromGlob = shift @ARGV;
225 my $toGlob = shift @ARGV;
226
227 my $pairs = globmap($fromGlob, $toGlob)
228 or die $File::GlobMapper::Error;
229
230 for my $pair (@$pairs)
231 {
232 my ($from, $to) = @$pair;
233 move $from => $to ;
234 }
235
236 Here is an example that renames all c files to cpp.
237
238 $ rename '*.c' '#1.cpp'
239
240 A few example globmaps
241
242 Below are a few examples of globmaps
243
244 To copy all your .c file to a backup directory
245
246 '</my/home/*.c>' '</my/backup/#1.c>'
247
248 If you want to compress all
249
250 '</my/home/*.[ch]>' '<*.gz>'
251
252 To uncompress
253
254 '</my/home/*.[ch].gz>' '</my/home/#1.#2>'
255
257 File::Glob
258
260 The File::GlobMapper module was written by Paul Marquess,
261 pmqs@cpan.org.
262
264 Copyright (c) 2005 Paul Marquess. All rights reserved. This program is
265 free software; you can redistribute it and/or modify it under the same
266 terms as Perl itself.
267
268
269
270perl v5.8.8 2007-06-18 File::GlobMapper(3)