readdir() problem

readdir() problem

am 02.11.2006 04:09:30 von cascade

First post - have found newsgroup to be a great help with little problems.

I am fairly new to perl (have written code in C and java), please try to
forgive me if a question I ask is lame or obvious . . .

I have written a small script that batch renames files with the same
extension within a nominated directory. This works fine, excepting a
mysterious problem I have with readdir(). Have done quite a few hours of
hunting for an answer to no avail, in the places I have seen referenced by
posts to this newsgroup on the net.

The problem is;
I am using readdir() to read in files to an array. Everytime I do it puts
the first filename at the very end of the array. Therefore, if I am trying
to rename the files within the directory the first file always ends up
last. This is very frustrating. I wrote a similar program that renames mp3
tracks which works well. I have tried a few variations, even cut and
pasted the code I used in the mp3 script but to no joy. The offending code
is . . .

use IO::File;

getFiles();

sub getFiles{

print("Enter full path to files to be renamed --> ");

chop($dirPath=);

if(!(opendir(DIR, $dirPath))){
print("\nNO SUCH DIRECTORY: $dirPath\n");
exit(0);
}

print("Please enter extension of files to be renamed --> ");

chop($ext=);

@fileArray= grep { /$ext$/ } readdir(DIR);

closedir(DIR);
}

My OS is Ubuntu Linux.

Two questions:

I have seen the module "use:switch" quite often in other (more advanced)
ppls scripts, could someone tell me briefly what it does?

Is there other
modules I should use when processing perl?

thanks if you have taken the time to answer . . .

Re: readdir() problem

am 02.11.2006 08:21:31 von someone

cascade wrote:
> First post - have found newsgroup to be a great help with little problems.
>
> I am fairly new to perl (have written code in C and java), please try to
> forgive me if a question I ask is lame or obvious . . .
>
> I have written a small script that batch renames files with the same
> extension within a nominated directory. This works fine, excepting a
> mysterious problem I have with readdir(). Have done quite a few hours of
> hunting for an answer to no avail, in the places I have seen referenced by
> posts to this newsgroup on the net.

You should have the Perl documentation installed on your hard drive along with
Perl. Try entering this command on a terminal:

perldoc -f readdir


If not you should be able to find it on the web at:

http://perldoc.perl.org/functions/readdir.html


> The problem is;
> I am using readdir() to read in files to an array. Everytime I do it puts
> the first filename at the very end of the array.

What do you mean by the "first" file name? File names are not, AFAIK, stored
in any particular order.


> Therefore, if I am trying
> to rename the files within the directory the first file always ends up
> last. This is very frustrating. I wrote a similar program that renames mp3
> tracks which works well. I have tried a few variations, even cut and
> pasted the code I used in the mp3 script but to no joy. The offending code
> is . . .
>
> use IO::File;
>
> getFiles();
>
> sub getFiles{
>
> print("Enter full path to files to be renamed --> ");
>
> chop($dirPath=);

You should use chomp() instead of chop().


> if(!(opendir(DIR, $dirPath))){
> print("\nNO SUCH DIRECTORY: $dirPath\n");
> exit(0);
> }
>
> print("Please enter extension of files to be renamed --> ");
>
> chop($ext=);

You should use chomp() instead of chop().


> @fileArray= grep { /$ext$/ } readdir(DIR);
>
> closedir(DIR);
> }

It is hard to say exactly what your problem is because you don't show what you
are attempting to do with the @fileArray array.


> My OS is Ubuntu Linux.
>
> Two questions:
>
> I have seen the module "use:switch" quite often in other (more advanced)
> ppls scripts, could someone tell me briefly what it does?

perldoc Switch

Or:

http://perldoc.perl.org/Switch.html


> Is there other
> modules I should use when processing perl?

use warnings;
use strict;



John
--
Perl isn't a toolbox, but a small machine shop where you can special-order
certain sorts of tools at low cost and in short order. -- Larry Wall

Re: readdir() problem

am 02.11.2006 10:08:16 von cascade

On Thu, 02 Nov 2006 07:21:31 +0000, John W. Krahn wrote:

> cascade wrote:
>> First post - have found newsgroup to be a great help with little problems.
>>
>> I am fairly new to perl (have written code in C and java), please try to
>> forgive me if a question I ask is lame or obvious . . .
>>
>> I have written a small script that batch renames files with the same
>> extension within a nominated directory. This works fine, excepting a
>> mysterious problem I have with readdir(). Have done quite a few hours of
>> hunting for an answer to no avail, in the places I have seen referenced by
>> posts to this newsgroup on the net.
>
> You should have the Perl documentation installed on your hard drive along with
> Perl. Try entering this command on a terminal:
>
> perldoc -f readdir

thanks, didn't know you could do that . . .

>
>
> If not you should be able to find it on the web at:
>
> http://perldoc.perl.org/functions/readdir.html

yes . . . done that

>
>
>> The problem is;
>> I am using readdir() to read in files to an array. Everytime I do it puts
>> the first filename at the very end of the array.
>
> What do you mean by the "first" file name? File names are not, AFAIK, stored
> in any particular order.

well, what I mean is the first file read from the directory, the files are
numbered , foo001.ext, foo002.ext, foo003 etc.
When the array prints it prints them in order (except that
first file always ends up last, which is why I posted 1st place).
I have tried sort(@fileArray) and I get a msg telling me its a useless
implementation, therefore I would have to assume that the array is already
sorted.


>
>
>> Therefore, if I am trying
>> to rename the files within the directory the first file always ends up
>> last. This is very frustrating. I wrote a similar program that renames
>> mp3 tracks which works well. I have tried a few variations, even cut
>> and pasted the code I used in the mp3 script but to no joy. The
>> offending code is . . .
>>
>> use IO::File;
>>
>> getFiles();
>>
>> sub getFiles{
>>
>> print("Enter full path to files to be renamed --> ");
>>
>> chop($dirPath=);
>
> You should use chomp() instead of chop().
>
>
>> if(!(opendir(DIR, $dirPath))){
>> print("\nNO SUCH DIRECTORY: $dirPath\n"); exit(0);
>> }
>> }
>> print("Please enter extension of files to be renamed --> ");
>>
>> chop($ext=);
>
> You should use chomp() instead of chop().
>
>
>> @fileArray= grep { /$ext$/ } readdir(DIR);
>>
>> closedir(DIR);
>> }
>> }
> It is hard to say exactly what your problem is because you don't show
> what you are attempting to do with the @fileArray array.

Ah, well maybe I didn't explain myself clearly . . .
I am trying to batch rename files in a directory with the same extension,
eg: foo001.ext becomes new001.ext, foo002.ext becomes new002.ext etc.

>
>
>> My OS is Ubuntu Linux.
>>
>> Two questions:
>>
>> I have seen the module "use:switch" quite often in other (more
>> advanced) ppls scripts, could someone tell me briefly what it does?
>
> perldoc Switch
>
> Or:
>
> http://perldoc.perl.org/Switch.html

yes, been there, I might be a bit thick or something, I was hoping for a
layman simple explanation . . .

>
>
>> Is there other
>> modules I should use when processing perl?
>
> use warnings;
> use strict;
>
>
>
> John
Thanks, John

Re: readdir() problem

am 02.11.2006 10:45:41 von Joe Smith

cascade wrote:

> I have tried sort(@fileArray) and I get a msg telling me its a useless
> implementation, therefore I would have to assume that the array is already
> sorted.

If you wrote the perl statement as

sort(@fileArray);

you should get "Useless use of sort in void context" because
that is _not_ the way to sort an array. You need

@fileArray = sort(@fileArray);

to store the results returned by the sort() function.

> the first file read from the directory, the files are
> numbered , foo001.ext, foo002.ext, foo003 etc.
> When the array prints it prints them in order (except that
> first file always ends up last, which is why I posted 1st place).

That sort of behavior is somewhat expected.

fedora4% perl -e 'open OUT,">foo$_.ext" for ("000".."030")'
fedora4% perl -le 'opendir DIR,"."; @a=readdir DIR; print "@a"'
foo013.ext foo023.ext foo012.ext foo021.ext foo014.ext foo006.ext
foo007.ext foo027.ext foo009.ext foo011.ext foo030.ext . foo024.ext
foo016.ext foo017.ext foo029.ext foo000.ext foo002.ext foo028.ext
foo019.ext foo004.ext foo026.ext foo022.ext foo001.ext foo003.ext
foo018.ext foo025.ext foo010.ext .. foo015.ext foo020.ext foo008.ext
foo005.ext
fedora4% ls -fx
foo013.ext foo023.ext foo012.ext foo021.ext foo014.ext foo006.ext
foo007.ext foo027.ext foo009.ext foo011.ext foo030.ext ./
foo024.ext foo016.ext foo017.ext foo029.ext foo000.ext foo002.ext
foo028.ext foo019.ext foo004.ext foo026.ext foo022.ext foo001.ext
foo003.ext foo018.ext foo025.ext foo010.ext ../ foo015.ext
foo020.ext foo008.ext foo005.ext
fedora4% find . -print | head
..
../foo013.ext
../foo023.ext
../foo012.ext
../foo021.ext
../foo014.ext
../foo006.ext
../foo007.ext
../foo027.ext
../foo009.ext

Directories in modern ext3 file systems are hashed by default.
This means that file names are not stored in the directory in the
same order that they were created.

fedora# dumpe2fs -h /dev/md0 | grep -i directory
Default directory hash: tea
Directory Hash Seed: 60f8bf71-5a37-4592-af41-1f4649ab6474

You had the right idea, just use sort() it the correct manner.
-Joe

Re: readdir() problem

am 02.11.2006 11:08:52 von cascade

Excellent Joe . . . much appreciated, you got the nail on the head, I was
using sort the wrong way . . . I am much relieved, I have spent a long
time trying to nut this out

cascade

On Thu, 02 Nov 2006 01:45:41 -0800, Joe Smith wrote:

> cascade wrote:
>
> > I have tried sort(@fileArray) and I get a msg telling me its a useless
> > implementation, therefore I would have to assume that the array is already
> > sorted.
>
> If you wrote the perl statement as
>
> sort(@fileArray);
>
> you should get "Useless use of sort in void context" because
> that is _not_ the way to sort an array. You need
>
> @fileArray = sort(@fileArray);
>
> to store the results returned by the sort() function.
>
> > the first file read from the directory, the files are
> > numbered , foo001.ext, foo002.ext, foo003 etc.
> > When the array prints it prints them in order (except that
> > first file always ends up last, which is why I posted 1st place).
>
> That sort of behavior is somewhat expected.
>
> fedora4% perl -e 'open OUT,">foo$_.ext" for ("000".."030")'
> fedora4% perl -le 'opendir DIR,"."; @a=readdir DIR; print "@a"'
> foo013.ext foo023.ext foo012.ext foo021.ext foo014.ext foo006.ext
> foo007.ext foo027.ext foo009.ext foo011.ext foo030.ext . foo024.ext
> foo016.ext foo017.ext foo029.ext foo000.ext foo002.ext foo028.ext
> foo019.ext foo004.ext foo026.ext foo022.ext foo001.ext foo003.ext
> foo018.ext foo025.ext foo010.ext .. foo015.ext foo020.ext foo008.ext
> foo005.ext
> fedora4% ls -fx
> foo013.ext foo023.ext foo012.ext foo021.ext foo014.ext foo006.ext
> foo007.ext foo027.ext foo009.ext foo011.ext foo030.ext ./
> foo024.ext foo016.ext foo017.ext foo029.ext foo000.ext foo002.ext
> foo028.ext foo019.ext foo004.ext foo026.ext foo022.ext foo001.ext
> foo003.ext foo018.ext foo025.ext foo010.ext ../ foo015.ext
> foo020.ext foo008.ext foo005.ext
> fedora4% find . -print | head
> .
> ./foo013.ext
> ./foo023.ext
> ./foo012.ext
> ./foo021.ext
> ./foo014.ext
> ./foo006.ext
> ./foo007.ext
> ./foo027.ext
> ./foo009.ext
>
> Directories in modern ext3 file systems are hashed by default.
> This means that file names are not stored in the directory in the
> same order that they were created.
>
> fedora# dumpe2fs -h /dev/md0 | grep -i directory
> Default directory hash: tea
> Directory Hash Seed: 60f8bf71-5a37-4592-af41-1f4649ab6474
>
> You had the right idea, just use sort() it the correct manner.
> -Joe

Re: readdir() problem

am 02.11.2006 11:40:10 von paduille.4060.mumia.w

On 11/01/2006 09:09 PM, cascade wrote:
> First post - have found newsgroup to be a great help with little problems.
>
> I am fairly new to perl (have written code in C and java), please try to
> forgive me if a question I ask is lame or obvious . . .
>
> I have written a small script that batch renames files with the same
> extension within a nominated directory. This works fine, excepting a
> mysterious problem I have with readdir(). Have done quite a few hours of
> hunting for an answer to no avail, in the places I have seen referenced by
> posts to this newsgroup on the net.
>
> The problem is;
> I am using readdir() to read in files to an array. Everytime I do it puts
> the first filename at the very end of the array. Therefore, if I am trying
> to rename the files within the directory the first file always ends up
> last. This is very frustrating. I wrote a similar program that renames mp3
> tracks which works well. I have tried a few variations, even cut and
> pasted the code I used in the mp3 script but to no joy. The offending code
> is . . .
>
> use IO::File;
>
> getFiles();
>
> sub getFiles{
>
> print("Enter full path to files to be renamed --> ");
>
> chop($dirPath=);
>
> if(!(opendir(DIR, $dirPath))){
> print("\nNO SUCH DIRECTORY: $dirPath\n");
> exit(0);
> }
>
> print("Please enter extension of files to be renamed --> ");
>
> chop($ext=);
>
> @fileArray= grep { /$ext$/ } readdir(DIR);
>
> closedir(DIR);
> }
>

On Debian 3.1, you have a "rename" command. Look at "man rename"

On my system, that rename command is a Perl script, so viewing it might
also help you.


> My OS is Ubuntu Linux.
>
> Two questions:
>
> I have seen the module "use:switch" quite often in other (more advanced)
> ppls scripts, could someone tell me briefly what it does?
>
> Is there other
> modules I should use when processing perl?
>
> thanks if you have taken the time to answer . . .
>
>

The Switch module adds a switch command to perl, but perl doesn't need a
switch command since there are so many ways to do "switch" without
Switch.pm in perl. Also, I've had some problems with the Switch module;
my opinion is that it's buggy.

perldoc Switch
perldoc perl
perldoc perlintro
perldoc -q switch
man perldoc



--
paduille.4060.mumia.w@earthlink.net

Re: readdir() problem

am 03.11.2006 13:52:22 von cascade

Thanks Mumia, much appreciated.

I am using rename elsewhere in the script.

Actually, I meant to ask about use:strict (duh!), not use:switch . . .

I didn't realise that someone might find the switch module buggy, so I
might check out the difference.

Before switch I used a string of if elsif else statements which I thought
looked a bit inelegant, also I guess I just missed it from C coding ;-)

thanks for the reply, cascade

On Thu, 02 Nov 2006 10:40:10 +0000, Mumia W. (reading news) wrote:

> On 11/01/2006 09:09 PM, cascade wrote:
>> First post - have found newsgroup to be a great help with little problems.
>>
>> I am fairly new to perl (have written code in C and java), please try to
>> forgive me if a question I ask is lame or obvious . . .
>>
>> I have written a small script that batch renames files with the same
>> extension within a nominated directory. This works fine, excepting a
>> mysterious problem I have with readdir(). Have done quite a few hours of
>> hunting for an answer to no avail, in the places I have seen referenced by
>> posts to this newsgroup on the net.
>>
>> The problem is;
>> I am using readdir() to read in files to an array. Everytime I do it puts
>> the first filename at the very end of the array. Therefore, if I am trying
>> to rename the files within the directory the first file always ends up
>> last. This is very frustrating. I wrote a similar program that renames mp3
>> tracks which works well. I have tried a few variations, even cut and
>> pasted the code I used in the mp3 script but to no joy. The offending code
>> is . . .
>>
>> use IO::File;
>>
>> getFiles();
>>
>> sub getFiles{
>>
>> print("Enter full path to files to be renamed --> ");
>>
>> chop($dirPath=);
>>
>> if(!(opendir(DIR, $dirPath))){
>> print("\nNO SUCH DIRECTORY: $dirPath\n");
>> exit(0);
>> }
>>
>> print("Please enter extension of files to be renamed --> ");
>>
>> chop($ext=);
>>
>> @fileArray= grep { /$ext$/ } readdir(DIR);
>>
>> closedir(DIR);
>> }
>>
>
> On Debian 3.1, you have a "rename" command. Look at "man rename"
>
> On my system, that rename command is a Perl script, so viewing it might
> also help you.
>
>
>> My OS is Ubuntu Linux.
>>
>> Two questions:
>>
>> I have seen the module "use:switch" quite often in other (more advanced)
>> ppls scripts, could someone tell me briefly what it does?
>>
>> Is there other
>> modules I should use when processing perl?
>>
>> thanks if you have taken the time to answer . . .
>>
>>
>
> The Switch module adds a switch command to perl, but perl doesn't need a
> switch command since there are so many ways to do "switch" without
> Switch.pm in perl. Also, I've had some problems with the Switch module;
> my opinion is that it's buggy.
>
> perldoc Switch
> perldoc perl
> perldoc perlintro
> perldoc -q switch
> man perldoc

Re: readdir() problem

am 05.11.2006 08:33:40 von Joe Smith

cascade wrote:
> Mumia W. (reading news) wrote:
>
>> On Debian 3.1, you have a "rename" command. Look at "man rename"
>>
>> On my system, that rename command is a Perl script, so viewing it might
>> also help you.
>>
>
> I am using rename elsewhere in the script.

I'm pretty sure that Mumia was talking about the rename command
(/usr/bin/rename, /usr/local/bin/rename) not the rename() function
inside of perl. On my system, it is in /usr/local/bin/rename.pl,
with the explicit ".pl" as a reminder that this command-line
utility takes perl syntax. As in

linux% rename.pl 's/\.tar\.gz/.tgz/' */*.tar.gz

to rename *.tar.gz to the *.tgz naming convention.

To follow Mumia's advice:

linux% man rename; less `which rename`

-Joe

P.S. Notice how I corrected your "top posting" and deleted quoted
material not germane to this part of the discussion.

Re: readdir() problem

am 05.11.2006 11:52:06 von cascade

On Sat, 04 Nov 2006 23:33:40 -0800, Joe Smith wrote:

> I'm pretty sure that Mumia was talking about the rename command
> (/usr/bin/rename, /usr/local/bin/rename) not the rename() function
> inside of perl. On my system, it is in /usr/local/bin/rename.pl,
> with the explicit ".pl" as a reminder that this command-line
> utility takes perl syntax. As in
>
> linux% rename.pl 's/\.tar\.gz/.tgz/' */*.tar.gz
>
> to rename *.tar.gz to the *.tgz naming convention.
>
> To follow Mumia's advice:
>
> linux% man rename; less `which rename`
>
> -Joe
>
> P.S. Notice how I corrected your "top posting" and deleted quoted
> material not germane to this part of the discussion.

Oh, ok . . . checked man rename . . .

Also, removed irrelevant info as you suggested, slowly getting the picture
I hope . . .

thanks for the useful input, Joe
cascade