?
Solved

Script to rename a file based on its directory structure

Posted on 2006-10-24
6
Medium Priority
?
244 Views
Last Modified: 2010-03-05
Hello,

I have hundreds of image files in multiple directories that I would like to rename. Essentially, I want to prepend the directory structure to the filename and leave the file in its original directory. I would also like it to log the changes that it makes to a single logfile. Please let me know if there is anything that I need to clarify.


As an example:

/dir1
   |-dir2
       |-image-001.jpg
       |-image-002.jpg


would become:
dir1_dir2_image-001.jpg
dir1_dir2_image-002.jpg


and the logfile would show:
image-001.jpg  dir1_dir2_image-001.jpg
image-002.jpg  dir1_dir2_image-002.jpg
0
Comment
Question by:austerhaus
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 
LVL 48

Expert Comment

by:Tintin
ID: 17800699
Much better/easier with a shell script

#!/bin/sh
LOG=/path/to/logfile

for file in `find /dir1 -name "*.jpg"`
do
  newfile=`echo $file|sed 's#/#_#g'`
  mv $file `dirname $file`/$newfile && echo "`basename $file` $newfile" >>$LOG
done
0
 
LVL 39

Expert Comment

by:Adam314
ID: 17804393
>>Much better/easier with a shell script
as long as you are on unix   :)

Basically the same code in perl:
#!/usr/bin/perl
use File::Find;
$LOG=/path/to/logfile

find(\&ProcessFile, "/dir1");

sub ProcessFile {
    return if $File::Find::name !~ /\.jpg/i;    #skip any non-jpg files
    return if !-f $File::Find::name;               #skip any non-files (eg: directories)
   
    $newfile=$File::Find::name;
    $newfile =~ s#/#_#g;
    rename $File::Find::name, $File::Find::dir . "/" . $newfile
   
    open(LG, ">>$LOG") or die "Couln't open log: $!\n";
    print LG $File::Find::name . ", " . $File::Find::dir . "/" . $newfile . "\n";
    close(LG);
}
0
 
LVL 1

Author Comment

by:austerhaus
ID: 17804620
Thasnks for the reply. Is there a way to modify this so that I am not required to manually specify the directory path? Basically, I would prefer if it simply prepended the directory structure from where the script is run down to the location of the file. I know my initial post sorta mucked up the the intention. I hope this is clearer:

A better example:
/root
   |home
      |dir1      
         |-dir2
             |-image-001.jpg
             |-image-002.jpg


would become:
dir1_dir2_image-001.jpg
dir1_dir2_image-002.jpg

...when I run the script from the home directory.


To get it to work, I had to change:

#!/bin/sh
LOG=logfile.txt
for file in `find /home/user/temp/test -name "*.jpg"`
do
  newfile=`echo $file|sed 's#/#_#g'`
  mv $file `dirname $file`/$newfile && echo "`basename $file` $newfile" >>$LOG
done

This gives me the following results:
_home_user_temp_test_dir2_images_image-001.jpg

when I started with this:
images_image-001.jpg
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 84

Expert Comment

by:ozo
ID: 17805644
cd $HOME
perl -MFile::Find -e 'find({no_chdir=>1,wanted=>sub{/\.jpg$/and($newfile=$_)=~s#(?<\!^.)/#_#g&&(rename $_,$newfile or warn "$newfile $!")&&print "$newfile\n"}},".")' >> logfile.txt

0
 
LVL 48

Accepted Solution

by:
Tintin earned 2000 total points
ID: 17806921
If you want it to run from your current directory, simple do:

#!/bin/sh
LOG=logfile.txt
HERE=`pwd`

for file in `find $HERE -name "*.jpg"`
do
  newfile=`echo $file|sed -e "s#$HERE/##" -e 's#/#_#g'`
  mv $file `dirname $file`/$newfile && echo "`basename $file` $newfile" >>$LOG
done
0
 
LVL 1

Author Comment

by:austerhaus
ID: 17814574
Great. Thank you for the assistance Tintin.
0

Featured Post

Want to be a Web Developer? Get Certified Today!

Enroll in the Certified Web Development Professional course package to learn HTML, Javascript, and PHP. Build a solid foundation to work toward your dream job!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (http://dilbert.com/strips/comic/2007-08…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans
Suggested Courses

741 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question