Re: How do u rename every file in a dir and sub?⭐
by rob_au (Abbot) on Dec 14, 2001 at 08:59 UTC
|
This code performs this task for you - It makes use of File::Find to find entries within the given path, ensures that they are actually files (stat and -f _) and then renames them. This could be made more precise by added exclusion matches. eg. return unless (m/\.mp3$/);
#!d:/perl/bin/perl -w
use File::Find;
use strict;
find ({
'wanted' => \&renamefile,
}, '/path/to/sub/directory');
sub renamefile {
my ($dev, $ino, $mode, $nlink, $uid, $gid);
return unless (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_)
+);
return unless (-f _);
rename $_, lc($_);
}
| [reply] [d/l] [select] |
Re: How do u rename every file in a dir and sub?
by robin (Chaplain) on Dec 15, 2001 at 02:34 UTC
|
If you're using a Unix system (e.g. Linux or Solaris) then the easiest way is not entirely Perl, but uses the find command to get the filenames, and Perl for the actual renaming:
find . -type f -exec \
perl -e 'rename($_, lc) || warn "$_: $!\n" for @ARGV' {} \;
That turns all the filenames in the current directory and below to lower case. If you're using a system which doesn't have the find command, you can use the find2perl utility (it comes with Perl) to generate a Perl script which will behave the same way. On Windows you can type:
find2perl . -type f -eval "rename $_, lc or warn qq{$_: $!\n}"
and then run the script that it outputs.
| [reply] [d/l] [select] |
Re: How do u rename every file in a dir and sub?
by JPaul (Hermit) on Dec 14, 2001 at 05:34 UTC
|
One way to do it would be something like this:
#!/usr/bin/perl -w
use strict;
# Open 'find' process to list files recursively with paths
open(FIND, "find |");
while(<FIND>) {
chomp;
next if $_ eq $0; # Don't rename ourself
rename($_, lc($_));
}
close(FIND);
It's not remarkably efficient, but it'll do your bidding.
JP | [reply] [d/l] |
Re: How to rename to lowercase every file in a directory and its subdirectories?
by Anonymous Monk on Sep 25, 2004 at 21:32 UTC
|
I'm no perl monk, but here's a tiny extension to Robin's answer, which also changes directory names to lowercase. A script which has just saved my skin.
#!/usr/bin/perl -w
use strict;
my $path_to_dir = shift;
dir("$path_to_dir");
sub dir {
rename "$_[0]","\L$_[0]";
$_[0]="\L$_[0]";
opendir(DIR,"$_[0]");
my @list_of_files = readdir(DIR);
foreach(@list_of_files) {
if($_ ne "." && $_ ne "..") {
if(-d "$_[0]/$_") {
dir("$_[0]/$_");
}
else {
rename "$_[0]/$_","$_[0]/"."\L$_";
}
}
}
}
| [reply] [d/l] |
|
rename "$_[0]","\L$_[0]";
This fails if the lowercase version of the directory already exists and is not empty.
Maybe worse is, it removes an existing but empty directory of the lowercase name.
So best to think about a warning:
unless ( -e "\L$_[0]" ) {
rename "$_[0]","\L$_[0]";
}
else
{
warn qq(been too afraid to move "$_[0]" to "\L$_[0]\E" - a file of
+ that name already exists.\n);
}
Edit:
One further thought: the script might save some time skipping the renaming
if the original file or directory already is all-lowercase.
Cheers, Sören | [reply] [d/l] [select] |
Re: How to rename to lowercase every file in a directory and its subdirectories?
by Alex the Serb (Monk) on Dec 20, 2001 at 19:03 UTC
|
you have to use recursion, because you dont know how much deep all subdirectories goes
#!/usr/bin/perl -w
use strict;
my $path_to_dir = shift;
dir("$path_to_dir");
sub dir {
opendir(DIR,"$_[0]");
my @list_of_files = readdir(DIR);
foreach(@list_of_files) {
if($_ ne "." && $_ ne "..") {
if(-d "$_[0]/$_") {
dir("$_[0]/$_");
}
else {
rename "$_[0]/$_","$_[0]/"."\L$_";
}
}
}
}
| [reply] [d/l] |
|
Pretty much the idea, but you seem a little confused by variables. Lightly edited (changed to a print statement to protect my innocent file names), here is your code:
#!/usr/bin/perl
use strict;
use warnings;
dir('.');
sub dir {
opendir( DIR, shift );
my @list_of_files = readdir(DIR);
foreach (@list_of_files) {
if (-d $_) {
dir($_) if $_ !~ /^\.\.?$/;
}
else {
print $_," would become \L$_,\n";
}
}
}
Things to note:
- If you mean to use a variable as a parameter, just do it, don't embed it in quotes
- Your use of $_[0] isn't needed, easier way to do the same is shown
- Post conditions and regexs are your friend, use them and they will reward you!
–hsm
"Never try to teach a pig to sing…it wastes your time and it annoys the pig." | [reply] [d/l] |
|
hsmyers - I cannot reliably make your code work. While the print function appears to show what was intended, it does not properly recurse through, not will it rename the files. However, Alex's code does give the intended results.
| [reply] |
Re: How to rename to lowercase every file in a directory and its subdirectories?
by Anonymous Monk on May 17, 2002 at 19:57 UTC
|
Simple, Safe, Fast, One-Line Solution
=============================================
To combine all the ideas into a safe, but fast, solution that won't overwrite existing files without warning, use:
find . -type f | perl -ne 'chomp; $src=$_; $lc = lc $src; if ($src ne $lc) { if (-e $lc) { print STDERR "Cannot lc $src (file $lc exists)\n"; } else { rename($src, $lc) || warn "$src: $!\n"; }}'
Notice the absence of "-exec" option for find. Using "-exec" causes one process for every file found (very slow).
This code snippet was quite useful at http://www.CleanFunny.com/, where many images originally used random naming conventions.
Cheers,
Vess Consulting
www.vess.com
Originally posted as a Categorized Answer. | [reply] [d/l] |
Re: How to rename to lowercase every file in a directory and its subdirectories?
by Anonymous Monk on Oct 27, 2002 at 23:51 UTC
|
| [reply] |
Re: How to rename to lowercase every file in a directory and its subdirectories?
by crazyinsomniac (Prior) on Oct 28, 2002 at 08:22 UTC
|
Re: How to rename to lowercase every file in a directory and its subdirectories?
Originally posted as a Categorized Answer. | [reply] |