File Coverage

blib/lib/File/Tools.pm
Criterion Covered Total %
statement 64 84 76.1
branch 12 18 66.6
condition 3 3 100.0
subroutine 21 27 77.7
pod 23 23 100.0
total 123 155 79.3


function.
line stmt bran cond sub pod time code
1             package File::Tools;
2 5     5   374644 use strict;
  5         47  
  5         184  
3 5     5   26 use warnings;
  5         11  
  5         134  
4              
5 5     5   25 use base 'Exporter';
  5         9  
  5         7621  
6             my @all = qw(
7             basename
8             catfile
9             compare
10             copy
11             cwd
12             date
13             dirname
14             fileparse
15             find
16             mkpath
17             move
18             popd
19             pushd
20             rm
21             rmtree
22             uniq
23             );
24              
25             our @EXPORT_OK = @all;
26             our %EXPORT_TAGS = (
27             all => \@all,
28             );
29              
30             our $VERSION = '0.10';
31              
32             my @DIRS; # used to implement pushd/popd
33              
34             sub _not_implemented {
35 5     5   46 die "Not implemented\n";
36             }
37             =head1 NAME
38              
39             File::Tools - UNIX tools implemented as Perl Modules and made available to other platforms as well
40              
41             =head1 SYNOPSIS
42              
43             use File::Tools qw(:all);
44              
45             my $str = cut {bytes => "3-7"}, "123456789";
46              
47             =head1 WARNING
48              
49             This is Alpha version of the module.
50             Interface of the functions will change and some of the functions might even disappear.
51              
52             =head1 REASON
53              
54             Why this module?
55              
56             =over 4
57              
58             =item *
59              
60             When I am writing filesystem related applications I always need to load several
61             standard modules such as File::Basename, Cwd, File::Copy, File::Path and maybe
62             others in order to have all the relevant functions.
63             I'd rather just use one module that will bring all the necessary functions.
64              
65             =item *
66              
67             On the other hand when I am in OOP mood I want all these functions to be methods of
68             a shell-programming-object. (Though probably L will answer this need better)
69              
70             =item *
71              
72             There are many useful commands available for the Unix Shell Programmer that usually need
73             much more coding than the Unix counterpart, specifically most of the Unix commands can work
74             recoursively on directory structures while in Perl one has to implement these.
75             There are some additional modules providing this functionality but then we get back again to
76             the previous issue.
77              
78             =back
79              
80             The goal of this module is to make it even easier to write scripts in Perl that
81             were traditionally easier to write in Shell.
82              
83             Partially we will provide functions similar to existing UNIX commands
84             and partially we will provide explanation on how to rewrite various Shell
85             constructs in Perl.
86              
87             =head1 DESCRIPTION
88              
89             =cut
90              
91             #=head2 awk
92             #
93             #Not implemented.
94             #
95             #=cut
96             #sub awk {
97             # _not_implemented();
98             #}
99              
100              
101             =head2 basename
102              
103             Given a path to a file or directory returns the last part of the path.
104              
105             See L for details.
106              
107             =cut
108             sub basename {
109 1     1 1 8 require File::Basename;
110 1         67 File::Basename::basename(@_);
111             }
112              
113             =head2 cat
114              
115             Not implemented.
116              
117             See L
118              
119             To process all the files on the command line and print them to the screen.
120              
121             while (my $line = <>) {
122             print $line;
123             }
124              
125             In shell cut is usually used to concatenate two or more files. That can be achived
126             with the previous code redirecting it to a file using > command line redirector.
127              
128             =cut
129             sub cat {
130 1     1 1 958 _not_implemented();
131             }
132              
133              
134             =head2 catfile
135              
136             Concatenating parts of a path in a platform independent way. See also L
137              
138             =cut
139             sub catfile {
140 3     3 1 3731 require File::Spec;
141 3         42 File::Spec->catfile(@_);
142             }
143              
144              
145              
146             =head2 cd
147              
148             Use the built in chdir function.
149              
150             =cut
151              
152              
153              
154              
155             =head2 chmod
156              
157             Use the built in chmod function.
158              
159             =cut
160              
161              
162              
163             =head2 chown
164              
165             For now use the built in chown function.
166              
167             It accepts only UID and GID values, but it is easy to retreive them:
168              
169             chown $uid, $gid, @files;
170             chown getpwnam($user), getgrname($group), @files;
171              
172             For recursive application use the L function.
173              
174             find( sub {chown $uid, $gid, $_}, @dirs);
175              
176             Windows: See chmod above.
177              
178             =cut
179              
180              
181             =head2 cmp
182              
183             See C
184              
185             =head2 compare
186              
187             Compare two files
188             See L for details.
189              
190             =cut
191             sub compare {
192 2     2 1 1769 require File::Compare;
193 2         987 File::Compare::compare(@_);
194             }
195              
196              
197             =head2 compress
198              
199             Not implemented.
200              
201             See some of the external modules
202              
203             =cut
204              
205              
206              
207              
208             =head2 copy
209              
210             Copy one file to another name.
211              
212             For details see L
213              
214             For now this does not provide recourseive copy. Later we will provide that
215             too using either one of these modules: L or L.
216              
217             =cut
218             sub copy {
219 1     1 1 780 require File::Copy;
220 1         2718 File::Copy::copy(@_);
221             }
222              
223              
224             =head2 cut
225              
226             Partially implemented but probably will be removed.
227              
228             Returns some of the fields of a given string (or strings).
229             As a UNIX command it can work on every line on STDIN or in a list of files.
230             When implementing it in Perl the most difficult part is to parse the parameters
231             in order to account for all the overlapping possibilities which should actually
232             be considered as user error.
233              
234             cut -b 1 file
235             cut -b 3,7 file
236             cut -b 3-7 file
237             cut -b -4,7-
238             order within the parameter string does not matter
239              
240             The same can be done in Perl for any single range:
241             substr $str, $start, $length;
242              
243             =cut
244             sub cut {
245             # --bytes
246             # --characters
247             # --fields
248             # --delimiter (in case --fields was used, defaults to TAB)
249 4     4 1 912 my ($args, $str) = @_;
250 4 50       12 if ($args->{bytes}) {
251 4         5 my $chars;
252 4         14 my @ranges = split /,/, $args->{bytes};
253 4         6 my %chars;
254 4         9 foreach my $range (@ranges) {
255 4 50       39 if ($range =~ /^-/) {
    50          
256 0         0 $range = "1$range";
257             } elsif ($range =~ /-$/) {
258 0         0 $range = $range . length($str)-1;
259             }
260 4 50       8 if ($range =~ /-/) {
261 0         0 my ($start, $end) = split /-/, $range;
262 0         0 $chars{$_}=1 for $start..$end;
263             } else {
264 4         11 $chars{$range} = 1;
265             }
266             }
267 4         5 my $ret = "";
268 4         14 foreach my $c (sort {$a <=> $b} keys %chars) {
  0         0  
269 4         15 $ret .= substr($str, $c-1, 1);
270             }
271 4         26 return $ret;
272             }
273              
274 0         0 return;
275             }
276              
277             =head2 cp
278              
279             See L instead.
280              
281             =cut
282              
283              
284             =head2 cwd
285              
286             Returns the current working directory similar to the pwd UNIX command.
287              
288             See L for details.
289              
290             =cut
291             sub cwd {
292 6     6 1 1150 require Cwd;
293 6         12863 Cwd::cwd();
294             }
295              
296             =head2 date
297              
298             Can be used to display time in the same formats the date command would do.
299              
300             See POSIX::strftime for details.
301              
302             =cut
303             sub date {
304 0     0 1 0 require POSIX;
305 0         0 POSIX::strftime(@_);
306             }
307              
308             =head2 df
309              
310             Not implemented.
311              
312             See L
313              
314             =cut
315             sub df {
316 1     1 1 608 _not_implemented();
317             }
318              
319             =head2 diff
320              
321             Not implemented.
322              
323             See L for a possible implementation.
324              
325             =cut
326             sub diff {
327 1     1 1 555 _not_implemented();
328             }
329              
330             =head2 dirname
331              
332             Given a path to a file or a directory this function returns the directory part.
333             (the whole string excpet the last part)
334              
335             See L for details.
336              
337             =cut
338             sub dirname {
339 1     1 1 5 require File::Basename;
340 1         39 File::Basename::dirname(@_);
341             }
342              
343             =head2 dirs
344              
345             Not implemented.
346              
347             =cut
348              
349              
350              
351             =head2 dos2unix
352              
353             Not implemented.
354              
355             =cut
356              
357              
358              
359             =head2 du
360              
361             Not implemented.
362              
363             L
364              
365             =cut
366              
367              
368             =head2 echo
369              
370             Not implemented.
371              
372             The print function in Perl prints to the screen (STDOUT or STDERR).
373              
374             If the given string is in double quotes "" the backslash-escaped characters take effect (-e mode).
375              
376             Within single quotes '', they don't have an effect.
377              
378             For printing new-line include \n withn the double quotes.
379              
380             =cut
381              
382              
383              
384             =head2 ed - editor
385              
386             Not implemented.
387              
388             =cut
389              
390              
391              
392             =head2 expr
393              
394             Not implemented.
395              
396             In Perl there is no need to use a special function to evaluate an expression.
397              
398             =over 4
399              
400             =item *
401              
402             match
403              
404             =item *
405              
406             substr - built in substr
407              
408             =item *
409              
410             index - built in index
411              
412             =item *
413              
414             length - built in length
415              
416             =back
417              
418             =cut
419              
420              
421              
422             =head2 file
423              
424             Not implemented.
425              
426             =cut
427              
428              
429              
430             =head2 fileparse
431              
432             This is not a UNIX command but it is provided by the same standard L
433             we already use.
434              
435             =cut
436             sub fileparse {
437 0     0 1 0 require File::Basename;
438 0         0 File::Basename::fileparse(@_);
439             }
440              
441              
442              
443             =head2 find
444              
445             See L for details.
446              
447             See also find2perl
448              
449             TODO: Probably will be replaced by L
450              
451             =cut
452             sub find {
453 0     0 1 0 require File::Find;
454 0         0 File::Find::find(@_);
455             }
456              
457              
458             =head2 ftp
459              
460             See L
461              
462             =cut
463              
464             =head2 move
465              
466             Move a file from one directory to any other directory with any name.
467              
468             One can use the built in rename function but it only works on the same filesystem.
469              
470             See L for details.
471              
472             =cut
473             sub move {
474 0     0 1 0 require File::Copy;
475 0         0 File::Copy::move(@_);
476             }
477              
478              
479              
480             =head2 getopts
481              
482             Not implemented.
483              
484             See L and L for possible implementations we will use here.
485              
486             =cut
487              
488              
489              
490              
491             =head2 grep
492              
493             Not implemented.
494              
495             A basic implementation of grep in Perl would be the following code:
496              
497             my $p = shift;
498             while (<>) {
499             print if /$p/
500             }
501              
502             but within real code we are going to be more interested doing such operation
503             on a list of values (possibly file lines) already in memory in an array or
504             piped in from an external file. For this one can use the grep build in function.
505              
506             @selected = grep { $_ =~ /REGEX/ } @original;
507              
508             TODO: See also L
509              
510             =cut
511              
512              
513              
514             =head2 gzip
515              
516              
517             Not implemented.
518              
519             =cut
520              
521              
522              
523             =head2 head
524              
525             Not implemented.
526              
527             =cut
528              
529              
530             =head2 id
531              
532             Normally the id command shows the current username, userid, group and gid.
533             In Perl one can access the current ireal UID as $< and the effective UID as $>.
534             The real GID is $( and the effective GID is $) of the current user.
535              
536             To get the username and the group name use the getpwuid($uid) and getpwgrid($gid)
537             functions respectively in scalar context.
538              
539              
540             =cut
541              
542              
543             =head2 kill
544              
545             See built in kill function.
546              
547             =cut
548              
549              
550              
551             =head2 less
552              
553             Not implemented.
554              
555             This is used in interactive mode only. No need to provide this functionality here.
556              
557             =cut
558              
559              
560             =head2 ln
561              
562             Not implemented.
563              
564             See the build in L and L functions.
565              
566             =cut
567              
568              
569             =head2 ls
570              
571             Not implemented.
572              
573             See glob and the opendir/readdir pair for listing filenames
574             use stat and lstat to retreive information needed for the -l
575             display mode of ls.
576              
577             =cut
578              
579              
580              
581             =head2 mail
582              
583             Sending e-mails.
584              
585             See L and L
586              
587             =cut
588              
589              
590             =head2 mkdir
591              
592             Not implemented.
593              
594             See the built in mkdir function.
595              
596             See also L
597              
598             =cut
599              
600              
601             =head2 mkpath
602              
603             Create a directory with all its parent directories.
604             See L for details.
605              
606             =cut
607             sub mkpath {
608 0     0 1 0 require File::Path;
609 0         0 File::Path::mkpath(@_);
610             }
611              
612              
613              
614             =head2 more
615              
616             Not implemented.
617              
618             This is used in interactive mode only. No need to provide this functionality here.
619              
620             =cut
621              
622              
623             =head2 mv
624              
625             See L instead.
626              
627             =cut
628              
629              
630             =head2 paste
631              
632             Not implemented.
633              
634             =cut
635              
636              
637             =head2 patch
638              
639             Not implemented.
640              
641             =cut
642              
643             =head2 ping
644              
645             See L
646              
647             =cut
648              
649             =head2 popd
650              
651             Change directory to last place where pushd was called.
652              
653             =cut
654             sub popd {
655 1     1 1 1792 my $dir = pop @DIRS;
656 1 50       68 if (chdir $dir) {
657 1         18 return cwd();
658             } else {
659 0         0 return;
660             }
661             }
662              
663             =head2 pushd
664              
665             Change directory and save the current directory in a stack. See also L.
666              
667             =cut
668             sub pushd {
669 1     1 1 27 my ($dir) = @_;
670 1         7 push @DIRS, cwd;
671 1 50       55 if (chdir $dir) {
672 1         15 return cwd();
673             } else {
674 0         0 return;
675             }
676             }
677              
678             =head2 printf
679              
680             Not implemented.
681              
682             See the build in L function.
683              
684             =cut
685              
686              
687             =head2 ps
688              
689             Not implemented.
690              
691             =cut
692              
693              
694              
695             =head2 pwd
696              
697             See L instead.
698              
699             =cut
700              
701              
702             =head2 read
703              
704             Not implemented.
705              
706             read x y z
707              
708             will read in a line from the keyboard (STDIN) and put the first word into x,
709             the second word in y and the third word in z
710              
711             In perl one can implement similar behavior by the following code:
712              
713             my ($x, $y, $z) = split /\s+/, ;
714              
715             =cut
716              
717              
718              
719             =head2 rm
720              
721             Not implemented.
722              
723             For removing files, see the built in L function.
724              
725             For removing directories see the built in L function.
726              
727             For removing trees (rm -r) see L
728              
729             See also L
730              
731             =cut
732             sub rm {
733 1     1 1 547 _not_implemented();
734             }
735              
736              
737              
738              
739              
740             =head2 rmdir
741              
742             Not implemented.
743              
744             For removing empty directories use the built in rmdir function.
745              
746             For removing tree see L
747              
748             =cut
749              
750              
751              
752              
753             =head2 rmtree
754              
755             Removes a whole directory tree. Similar to rm -rf.
756             See also L
757              
758             =cut
759             sub rmtree {
760 0     0 1 0 require File::Path;
761 0         0 File::Path::rmtree(@_);
762             }
763              
764              
765             =head2 scp
766              
767             See also L
768              
769             =cut
770              
771              
772              
773             #=head2 sed
774             #
775             #Not implemented.
776             #
777             #=cut
778             #sub sed {
779             # _not_implemented();
780             #}
781              
782              
783             =head2 slurp
784              
785             =cut
786             sub slurp {
787 3     3 1 1772 my $content = "";
788 3         9 foreach my $filename (@_) {
789 6 100       236 if (open my $fh, "<", $filename) {
790 5         29 local $/ = undef;
791 5         254 $content .= <$fh>;
792             } else {
793 1         17 warn "Could not open '$filename'\n";
794             }
795             }
796 3         16 return $content;
797             }
798              
799              
800             =head2 snmp
801              
802             L
803              
804             =cut
805              
806              
807             =head2 ssh
808              
809             L
810              
811             =cut
812              
813              
814             =head2 shift
815              
816             Not implemented.
817              
818             =cut
819              
820              
821              
822             =head2 sort
823              
824             Not implemented.
825              
826             See the built in sort function.
827              
828             =cut
829              
830              
831              
832              
833             =head2 tail
834              
835             Not implemented.
836              
837             Return the last n lines of a file, n defaults to 10
838              
839             =cut
840             sub tail {
841 1     1 1 538 _not_implemented();
842             }
843              
844              
845             =head2 tar
846              
847             Not implemented.
848              
849             See L
850              
851             =cut
852              
853             =head2 telnet
854              
855             L
856              
857             =cut
858              
859              
860             =head2 time
861              
862             See also L
863              
864             =cut
865              
866              
867             =head2 touch
868              
869             Not implemented.
870              
871             =head2 tr
872              
873             Not implemented.
874              
875             See the built in L
876              
877              
878             =head2 umask
879              
880             Not implemented.
881              
882             =cut
883              
884              
885             =head2 uniq
886              
887             The uniq unix command eliminates duplicate values following each other
888             but does not enforce uniqueness through the whole input.
889             For examle for the following list of input values: a a a b a a a
890             ths UNIX uniq would return a b a
891              
892             For completeness we also provide uniqunix that behaves just like the UNIX command.
893              
894             See also L
895              
896             =cut
897             sub uniq {
898 3     3 1 86 my (@uniq, %seen);
899 3         7 for (@_) {
900 14 100       38 push @uniq, $_ if not $seen{$_}++;
901             }
902 3         21 return @uniq;
903             }
904              
905             =head2 uniqunix
906              
907             Similar to the UNIX uniq command.
908              
909             =cut
910             sub uniqunix {
911 3     3 1 8 my (@uniq, $last);
912 3         7 for (@_) {
913 14 100 100     43 next if defined $last and $last eq $_;
914 12         14 $last = $_;
915 12         20 push @uniq, $last;
916             }
917 3         24 return @uniq;
918             }
919              
920              
921             =head2 unix2dos
922              
923             Not implemented.
924              
925             =head2 wc
926              
927             Not implemented.
928              
929             =head2 who
930              
931             Not implemented.
932              
933             =head2 who am i
934              
935             Not implemented.
936              
937             =head2 zip
938              
939             Not implemented.
940              
941              
942             =head2 redirections and pipe
943              
944             <
945             >
946             <
947             |
948              
949             Ctr-Z, & fg, bg
950             set %ENV
951              
952             =head2 Arguments
953              
954             $#, $*, $1, $2, ...
955              
956             $$ - is also available in Perl as $$
957              
958             =head2 Other
959              
960             $? error code of last command
961              
962             if test ...
963             string operators
964              
965             =head1 TODO
966              
967             File::Basename::fileparse_set_fstype
968             File::Compare::compare_text
969             File::Compare::cmp
970             File::Copy::syscopy
971             File::Find
972             File::Spec
973             File::Temp
974              
975             =head1 AUTHOR
976              
977             Gabor Szabo
978              
979             =head1 Copyright
980              
981             Copyright 2006-2012 by Gabor Szabo .
982              
983             =head1 LICENSE
984              
985             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
986              
987             See L
988              
989             =head1 SEE ALSO
990              
991             Tim Maher has a book called Miniperl http://books.perl.org/book/240 that might be very useful.
992             I have not seen it yet, but according to what I know about it it should be a good one.
993              
994             L
995              
996             The UNIX Reconstruction Project, L
997              
998             L
999              
1000              
1001             L
1002              
1003             Related Discussions:
1004              
1005             L
1006              
1007             =cut
1008              
1009             1;