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