Using File::Find and only manipulating 1 file per directory.

S

soren625

I am rather new to Perl and I'm looking for a little direction.

How can I use File::Find to step recursively through a directory tree
and then only manipulate *one* file per directory it encounters. What I
am trying to do specifically is copy the first image file in each
directory up to the next highest directory ("../"). Then I'd like to
rename it with the directory name it came from (in other words, copy it
from "/images/image1.jpg" to "/images.jpg")

I am able to copy *all* images to the next highest directory using the
following code:



#!/usr/bin/perl

use File::Find;
use File::Copy;
use Cwd;

find(\&wanted, cwd);

sub wanted {
if(/(jpg|jpeg|jpe|png|bmp|gif)$/i) {
copy $_, "../$_"
}
}



How can I get it to copy only the first image it encounters in any
directory *and* rename it with the directory name it came from?

Thanks
 
J

Joe Smith

soren625 said:
How can I use File::Find to step recursively through a directory tree
and then only manipulate *one* file per directory it encounters.

use File::Find;
my %files;
sub wanted {
$files{$File::Find::dir} = $_ if -f $_
and not defined $files{$File::Find::dir};
}
find(\&wanted, @ARGV);
print "$files{$_} in $_\n" foreach sort keys %files;

-Joe
 
S

soren625

This works great! Thanks!

Now anyone want to tackle renaming the copied file with the folder name
it came from?

I've tried a bunch of things, but just can't seem to get it to work.
 
A

A. Sinan Unur

This works great! Thanks!

What works?
Now anyone want to tackle renaming the copied file with the folder name
it came from?

How much are you offering?
I've tried a bunch of things, but just can't seem to get it to work.

What have your tried? What hasn't worked?

Please see the posting guidelines for this group.

Sinan
 
S

soren625

Sorry, the code edited by Jim Gibson works (using the 'next if').

I am not prepared to offer anything but immense gratitiude for any help
I get :)

Specifically I've tried using the $File::Find::dir variable to rename
the file moved

(i.e. after the line: copy $_, "../$_" I add:
rename "../$_", "../$File::Find::$dir";
I know I'm not allowing for file extensions here, but that's an issue I
think I can tackle)

It seems that, contrary to what I'm reading in the Perldoc for
File::Find, $File::Find::dir contains the full path of the current
directory, not just the current directory name. (Incidentally, I'm
working with Perl on Windows -- but this script will utimately be used
on Linux.)

Obviously I'm relatively new to Perl (which is why I'm posting
questions here instead of answers).
 
S

soren625

OK, you win -- I give up.

(I hate newsgroups for all their snooty know-it-alls and flip answers)
 
S

soren625

Thanks (again), Jim, for the helpful answer.

I've read over the guidelines, please tell me what I'm doing wrong.

ARRGH -- you are right -- I had read the perldoc wrong. (Which makes me
even more self-conscious about whatever I'm doing wrong in my posting.
(why is it that posting to usenet groups always makes my palms all
sweaty?).

The program to which I was referring was posted (in it's entirety) in
my original post.
I did not repost in the interest of brevity. (Which, I guess, was not
really necessary, so point taken -- I will be very explicit about the
program I am referring to in the future).

Thanks again for your help.
 
S

soren625

<snip>
You are not quoting anything. See "Use an effective followup style"
</snip>

OK, sorry -- using Google Groups.

Anything else?
 
A

A. Sinan Unur

<snip>
You are not quoting anything. See "Use an effective followup style"
</snip>

OK, sorry -- using Google Groups.

You are still not quoting appropriately. The proper way to post using GG
has been posted here many, many times. A cursory search would have given
you a clue. You need to attribute the quotation properly.

"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Anything else?

Instead of posting self-contained code, you are expecting people to go
back and forth, pasting updated lines in the places you intended them to
go etc etc. You need to do some work to make it easier for people to
help you.

Sinan
 
S

soren625

Paul said:
What, exactly, is your point? I'm using Google Groups as well.

http://groups.google.com/support/bin/answer.py?answer=14213&topic=250

Paul Lalli

My point was that I was apologizing and changing my evil ways (as you
may have noticed -- is there anything about really reading posts in
those guidelines?)

<curtsy>
Please accept this as my formal apology -- no excuses.
</curtsy>

I have always been of the opinion that when someone has knowlegde to
share via a resource such as the Internet, it should be shared
liberally and graciously. Whenever I have had opportunity to do so I
have attempted to be understanding and even open-minded -- perhaps the
person asking the question doesn't even know *how* to ask his or her
particular question. Often, the person gets a stupid, snobby link about
how to ask effective questions slapped in his face, because this
clearly establishes the intellectual dominance (and ultimate laziness)
of the replier.

It's curious that of the four people that have replied to my o.p., only
two have even attempted to graciously provide an answer to my question.
 
M

Matt Garrish

soren625 said:
It's curious that of the four people that have replied to my o.p., only
two have even attempted to graciously provide an answer to my question.

Welcome to Usenet...

Matt
 
P

Paul Lalli

soren625 said:
My point was that I was apologizing and changing my evil ways

No, you were simultaneously apologizing and attempting to justify your
evil ways. I was pointing out that your justification is invalid
<curtsy>
Please accept this as my formal apology -- no excuses.
</curtsy>

Apology accepted.
Often, the person gets a stupid, snobby link about
how to ask effective questions slapped in his face, because this
clearly establishes the intellectual dominance (and ultimate laziness)
of the replier.

On the contrary. Informing a questioner of how to ask an effective
question is of direct benefit to the questioner himself. The better
the question you ask, the better the answer you will receive.

As for Laziness, I have to wonder if you realize just how absurd that
theory is. Everyone on this group - every single person - is here as a
volunteer. No one is getting any monetary or any other kind of benefit
by answering any questions. How on earth can you claim that anyone is
being "lazy" by offering an answer of any kind, simply because it is
not the answer you preferred? By giving the questioner the information
needed to ask an effective question, a responder is giving the
questioner a second chance - therefore doubling his potential time
involved in answering the question. A "lazy" person would simply
ignore the question altogether.
It's curious that of the four people that have replied to my o.p., only
two have even attempted to graciously provide an answer to my question.

It is curious that you believe you have any right or expectation to
receive exactly the kind of answer you wish to receive - at no cost to
you, of course - while complaining about following the recommended
procedures for asking a question in the first place.

Paul Lalli
 
A

axel

That's not a response to the example I gave.
In any event, I agree that directing someone to peripheral information
is always helpful. However, it comes across as snide when that's the
sole response given. It minimizes that person's participation on the
board. Why not answer the question they meant, (instead of the question
they asked) and then point them to some basic resource or other info?

I saw two of your posts and had not the faintest idea what you
meant because the questions made no sense. Therefore those responses
which directed you to the the guidelines of how to post properly
were quite correct and the only meaningfully reply to make.

`I don't know what you mean by "glory",' Alice said.

Humpty Dumpty smiled contemptuously. `Of course you don't -- till
I tell you. I meant "there's a nice knock-down argument for you!"'

`But "glory" doesn't mean "a nice knock-down argument",' Alice
objected.

`When I use a word,' Humpty Dumpty said, in rather a scornful tone,
`it means just what I choose it to mean -- neither more nor less.'

(Lewis Carroll: Alice Through the Looking Glass)

Axel
 
S

soren625

I saw two of your posts and had not the faintest idea what you
meant because the questions made no sense.

.... I suppose if you didn't want them to make sense (I can only guess
that's waht you're getting at).

I'm sorry if my questions weren't as clear as necessary for you to
quite get your mind around them. Perhaps I can restate...

I have a directory structure with several subfolders, each subfolder
contains several image files (jpeg, gif, png, etc.).
I want to write a perl script that will recursively step through each
directory in the tree. For each directory, I want it to copy one image
file from the current directory to the current directory's parent
directory. (By current directory, I mean the one it is "in" as it
recurses.) I also would like the copied file to be renamed to match the
directory it was copied from. For example: /images/image1.jpg copied to
/images.jpg. Again, I realize that I would have to do some silly things
to get the extension back, etc.

This is what I have thus far:

#!/usr/bin/perl

use File::Find;
use File::Copy;
use Cwd;

my %directory;

find(\&wanted, cwd);

sub wanted {
if(/(jpg|jpeg|jpe|png|bmp|gif)$/i) {
next if $directory{$File::Find::dir};
copy $_, "../$_";
$directory{$File::Find::dir} = 1;

}
}


This effectively copies the images as desired, but I haven't had any
success with the renaming part. It was recommended that I use

my( $dir ) = $File::Find::dir =~ m|([^/]*)$|;

to get the current directory (without the full path), and I can
understand how that works, but I'm not sure how to implement it in the
code above.
 
A

axel

soren625 said:
(e-mail address removed) wrote:
... I suppose if you didn't want them to make sense (I can only guess
that's waht you're getting at).

What sense was I supposed to make of the following which was the first question
I read?

Now anyone want to tackle renaming the copied file with the folder name
it came from?

I've tried a bunch of things, but just can't seem to get it to work.

Axel
 
S

soren625

What sense was I supposed to make of the following which was the first question
I read?

Now anyone want to tackle renaming the copied file with the folder name
it came from?

I've tried a bunch of things, but just can't seem to get it to work.

It does make sense (grammatically), e.g., you can understand what it
means. It does require the context of my first post. Follow up style,
quoting, etc. has been addressed already though.
 
S

soren625

Jim said:
Try the following ...

Egad Jim, you are the man. People like you are what newsgroups are [or
should be] all about. Profuse thank-yous for your help and kind
instruction.

Now to the Batcave to dissect your code -- I have much to learn.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top