Find file names with certain extensions - perl

I want to search a directory for file names with any of the following extensions: .srt, .sub, .txt, .ass, .ssa.
I would appreciate any input.

The simplest way is to use glob:
chdir $directory;
my #files = glob '*.srt *.sub *.txt *.ass *.ssa';
Another way is to use readdir, but then you have to filter the files yourself, e.g. by using grep:
open my $dir_handle, $directory or die $!;
my #files = grep /\.(?:srt|sub|txt|ass|ssa)\z/, readdir $dir_handle;

And if you need to search through an entire directory tree, use File::Find.

Related

Perl chdir fails with a glob pattern

I am trying to do cd in my perl script. I am using the below command:
chdir "/home/test/test1/test2/perl*";
perl* value is actually perl_0122_2044, but this value may vary.
The above chdir command is not doing cd to the path. Am I doing something wrong?
chdir does not accept * and other expansion characters in the argument. Use glob or something similar for this to extract a single directory, then chdir to that. For example, this changes directory to the first /home/test/test1/test2/perl* it finds:
$dir = (glob "/home/test/test1/test2/perl*")[0];
# only change dir if any dir was found:
if (-d $dir) {
# fail if cannot change dir (or, even better, use autodie):
chdir $dir or die "Could not change to $dir: $!";
}
chdir expects a path, not a wildcard. Use glob to expand the wildcard:
my ($dir) = glob "/home/test/test1/test2/perl*";
chdir $dir or die "$dir: $!";
If there are multiple expansions, the first one will be used.
In similar vein, glob is handled by a module in raku https://modules.raku.org/dist/IO::Glob

chdir in perl using two strings: chdir "/home/$dir1/$dir2"

I have two strings: $dir1 and $dir2. I want to use chdir as shown below:
chdir "/home/$dir1/$dir2";
when I try this it doesn't change the directory. I checked the current working directory same as before
Is there any way to do this?
Typically I write that as:
use v5.10;
use File::Spec::Functions;
my $dir = catfile( '/home', $dir1, $dir2 );
die "Dir <$dir> isn't a directory or doesn't exist" unless -e -d $dir;
chdir $dir or die "Could not change to <$dir>: $!";
Whenever you do something with the system, check the results to ensure it happened.
And, curiously, I didn't realize that Pearson's sample chapter of my book Effective Perl Programming is the one that covers stacked file test operators.

How to copy the folder from one directory to another in perl?

I want to copy the folder from one directory to another.
For Example
I have folder in D drive like Sample it that itself contain many folder.I want to copy this sample folder with its sub folders to some other drive.Here i have done something but it copies only the files.
#!/usr/bin/env perl
use strict;
use warnings;
use File::Copy,
my $source_dir = "aa";
my $target_dir = "bb";
opendir(my $DIR, $source_dir) || die "can't opendir $source_dir: $!";
my #files = readdir($DIR);
foreach my $t (#files)
{
if(-f "$source_dir/$t" ) {
#Check with -f only for files (no directories)
copy "$source_dir/$t", "$target_dir/$t";
}
}
closedir($DIR);
Please help with this...
Thanks in advance
You need to use either the File::Copy::Recursive module, which has a number of related functions from which you probably want dircopy; or the File::Mirror module, which has a mirror function that does the same as dircopy, plus a recursive function that allows you to provide a block of code to control exactly how the nodes will be copied.
use strict;
use warnings;
use File::Copy::Recursive qw(dircopy);
dircopy($source_dir,$target_dir) or die("$!\n");

Moving files into different folders/directories based on their name

I have a directory or folder consisting of hundreds of files. They are named and arranged alphabatically. I want to move the files into directories or folders according to the first character of their name (i.e. files starting with a into one folder, files starting with r into another folder, etc).
Is there a way to do it without using CPAN modules?
Are the files all in that one folder, or are they in subfolders? If they are all in a single folder, you can use opendir to access the directory, and then readdir to read the file names and copy them elsewhere (using File::Copy module's move or copy function.
use strict;
use warnings;
use autodie;
use File::Copy; #Gives you access to the "move" command
use constant {
FROM_DIR => "the.directory.you.want.to.read",
TO_DIR => "the.directory.you want.to.move.the.files.to",
};
#Opens FROM_DIR, ao I can read from it
opendir my $dir, FROM_DIR;
# Loopa through the directory
while (my $file = readdir $dir) {
next if ($file eq "." or $file eq "..");
my $from = FROM_DIR . "/" . "$file";
move $from, TO_DIR;
}
This doesn't do exactly what you want, but it should give you the idea. Basically, I'm using opendir and readdir to read the files in the directory and I'm using move to move them to another directory.
I used the File::Copy module, but this is included in all Perl distributions, so it's not a CPAN module that must be installed.
Use glob(), or the built-in File::Find to build a list of files for each starting letter.

How do I search a directory for all .XXX files and get a list of them in Perl?

I need to search in a directory for all the files that end in .123.
How do I (using Perl) get a list of those files?
Simply:
#files = glob "$dirname/*.123";
One way is to use glob:
use warnings;
use strict;
my #files = grep { -f } glob '*.123';
glob should do the job.
If you want to search recursively, you can use File::Find.