Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Use of special character "*" to retrieve the contents

by dk27 (Novice)
on Jun 07, 2017 at 12:55 UTC ( [id://1192265]=perlquestion: print w/replies, xml ) Need Help??

dk27 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I have a path which looks like this:

"$var1/$var2/$var3/*.ksh"

I need to copy all files with .ksh extension from the given path using perl. $var1, $var2 & $var3 are derived using various logic used in the program. I cannot use single quotes coz then it wont give me the value of elements $var and within double quotes, * is not being detected the way I want it. Can someone help me with this? <\p>

Replies are listed 'Best First'.
Re: Use of special character "*" to retrieve the contents
by shmem (Chancellor) on Jun 07, 2017 at 13:05 UTC

    See glob.

    for (glob "$var1/$var2/$var3/*.ksh") { print "$_\n"; }

    For portability, it is better to use File::Spec:

    use File::Spec; ... my $pat = File::Spec->catfile($var1,$var2,$var3,'*.ksh'); for(glob $pat) { print "$_\n"; }
    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

      When I see the use of glob I often feel compelled to point out that it has its caveats, such as how it handles whitespace in its argument, and also that it does not list filenames beginning with a dot by default (which might be surprising to users when compared to readdir or File::Find). A thorough read of glob and File::Glob, which implements the former, is recommended.

      Update: While File::Spec is often very good advice, I looked into this a bit, and note that the File::Glob doc discusses how on Win32, backslashes can interfere with escaping, and that forward slashes are recommended.

Re: Use of special character "*" to retrieve the contents
by Eily (Monsignor) on Jun 07, 2017 at 13:00 UTC

    * wouldn't do what you want in single quotes either. glob will give you the list of files that match your pattern: my @files = glob "$var1/$var2/$var3/*.ksh"

    Edit: I forgot the call to glob in my example :D, thanks haukex!

Re: Use of special character "*" to retrieve the contents
by choroba (Cardinal) on Jun 07, 2017 at 16:43 UTC
    Another library for path handling with a nice interface is Path::Tiny :
    #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; use Path::Tiny; my $var1 = '/home/choroba'; my $var2 = 'perl5'; say for path($var1, $var2)->children(qr/\.ksh$/);
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Use of special character "*" to retrieve the contents
by thanos1983 (Parson) on Jun 07, 2017 at 13:30 UTC

    Hello dk27,

    What about some alternatives? Such as File::Find

    #!/usr/bin/env perl use warnings; use strict; use File::Find; my $location="$var1/$var2/$var3/"; sub find_ksh { my $F = $File::Find::name; if ($F =~ /ksh$/ ) { print "$F\n"; } } find({ wanted => \&find_ksh, no_chdir=>1}, $location);

    Or readdir:

    opendir(my $dh, $some_dir) || die "Can't opendir $some_dir: $!"; my @files= map{s/\.[^.]+$//;$_}grep {/\.ksh$/} readdir DIR; closedir $dh;

    Both solutions are untested but they should work straight out of the box.

    Update: Also if you are running linuxOS or Cygwin terminal:

    Update3: as monk haukex pointed out using back ticks is not a good option, read the link on his response bellow why.

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $path = shift || '.'; my @files = `find $path -name '*.ksh' -o -name '*.txt'`; chomp @files; print Dumper \@files;

    WindowsOS with Cygwin:

    my @files = `find $path \( -name '*.ksh' -o -name '*.txt' \)`;

    Update2: Similar question with some maybe useful answers combining regex on search see (Re: File::Find find several strings in one directory).

    Hope this helps.

    Seeking for Perl wisdom...on the process of learning...not there...yet!

      It's important to note there is a difference between readdir/glob and File::Find/find: the latter recurses into subdirectories as well. As for running external commands, I wrote about that, including the potential security risks, at length here. At the very least I would recommend using something like IPC::System::Simple's capturex, e.g. my @files = capturex("find",$path,qw/ ( -name *.ksh -o -name *.txt ) /);

        "... the latter recurses..."

        But fortunately there is -maxdepth 0. From find:

        -maxdepth n Always true; descend at most n directory levels below the + command line arguments. If any -maxdepth primary is specified, it applies to the entire +expression even if it would not normally be evaluated. ``-maxdepth 0'' limits the whole +search to the command line argu- ments.

        Best regards, Karl

        «The Crux of the Biscuit is the Apostrophe»

        Furthermore I consider that Donald Trump must be impeached as soon as possible

      Of course, this will fall apart a bit when fed "$var7/$var8/test*.dat".

      Imagine their surprise, getting back a list of *.kshfiles from that input. :-)

Re: Use of special character "*" to retrieve the contents
by haukex (Archbishop) on Jun 07, 2017 at 14:57 UTC

    Here's another way to do it, using Path::Class, which can also do the copying for you:

    use Path::Class qw/file dir/; for my $file ( dir($var1,$var2,$var3)->children ) { next if $file->is_dir || $file->basename !~ /.+\.ksh$/; $file->copy_to($target) or die "Failed to copy $file to $target"; }

    Note this will copy filenames beginning with a dot as well.

Re: Use of special character "*" to retrieve the contents
by dk27 (Novice) on Jun 07, 2017 at 14:56 UTC
    Thanks a lot guys for prompt reply. I got it to work using glob :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1192265]
Approved by Eily
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (3)
As of 2024-04-18 19:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found