Shellscript to rearrange filenames in directories

below is the script to rename filenames ending with .pdf extension.
I want the script to enter directories and search for all pdf and then if it is in the format file_amb_2008.pdf , then change it to 2008_amb_file.pdf, and this script should work only for .pdf files.

help required to make the script run in all directories. Right now it works for only the directory is runs in.

The script is:
for file in $(ls -1)
do
newfile="$(echo $file | sed 's/\(.*\)_\(.*\)_\(.*\)..../\3_\2_\1.pdf/')"
mv $file $newfile
done

Also i want it to rename files only in the format file_amb_2008.pdf to 2008_amb_file.pdf and ignore the .txt or other files.
plz help.
thanks.

You can do this using the 'find' command. Just replace the 'ls -1' part with 'find . -type f -name "*.pdf"'.

If you feel more adventurous, take a look at find's -exec option to do everything in one command instead.

thanks for the reply,
i modified the script as per your suggestion to:

for file in $(find /home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/ -type f -name "*.pdf")
do
  newfile="$(echo $file | sed 's/\(.*\)_\(.*\)_\(.*\)..../\3_\2_\1.pdf/')"
  mv $file $newfile
done

But am getting error:
$ sh rearrange_final.sh
mv: cannot move `/home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/Benzoic-ben_MMCL_2009.pdf' to `2009_MMCL_/home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/Benzoic-ben.pdf': No such file or directory

what do you suggest?

The pattern match in sed is a bit too agressive, try changing it to:

sed 's%(.*)/(.*)_(.*)_(.*)\.pdf$%\1/\4_\3_\2.pdf%'

(ie I've added another match to catch everything up to the last / in the filename)
Not tested but it should do the job.

its giving the error below
sed: -e expression #1, char 44: invalid reference \4 on `s' command's RHS
mv: missing file argument
Try `mv --help' for more information.

Also when I try the script below:

for file in $(find /home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names -type f -name "*.pdf")
do
  newfile="$(echo $file | sed 's/\(.*\)_\(.*\)_\(.*\)..../\3_\2_\1.pdf/')"
  mv $file $newfile
done

I get following error:

mv: cannot move `/home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/Benzoic-ben_MMCL_2009.pdf' to `2009_MMCL_/home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/Benzoic-ben.pdf': No such file or directory

but what I expect is:

moved `/home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/Benzoic-ben_MMCL_2009.pdf' to `/home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/2009_MMCL_Benzoic-ben.pdf'

Check the final file names in both above cases.
thanks!

---------- Post updated 08-18-09 at 11:53 AM ---------- Previous update was 08-17-09 at 01:47 PM ----------

bump for the issue

just a little modification to ur code and it is working for me...

 
for file in $(find /home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/  -type f -name "*.pdf")
do
  newfile="$(echo ${file##*/} | sed 's/\(.*\)_\(.*\)_\(.*\)..../\3_\2_\1.pdf/')"
  mv $file $newfile
  echo "Moved"
done
 

hey thanks, the script is working fine, but just noticed one undesirable result.

if you noticed , In the find command I specified the location of where the pdb's may be located, but I may have multiple folders with many pdb's in them, now the above script is moving them from their location renaming them and placing all of them in the directory specified in the find command.
I want all of them to be replaced in their original locations itself, not move them to another location.
thanks!

The reason is very simple why you had all these chaos !!

The regex you used is greedy !! So make it non greedy and check.

for file in $(find /home/sathiya/t1/ -type f -name "*.pdf")
do
  echo $file 
  newfile="$(echo $file | sed 's/\(.*\)\(.*?\)_\(.*?\)_\(.*?\).pdf$/\4\3_\2_\1.pdf/')"
  echo $newfile
done

Tested, works as expected !

Let us know whether it helps. Also it is the solution for the previous problem you are facing, it will not move all the files to the script where the find is placed, it will rename all the files in the appropriate directories itself as with your mv command.

/home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/Benzoic-zinc_AMDL_2009.pdf
/home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/Benzoic-zinc_AMDL_2009.pdf
/home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/folder2/folder3/Bolsch-fing_TMDLL_2007.pdf
/home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/folder2/folder3/Bolsch-fing_TMDLL_2007.pdf
/home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/folder2/Tandge-Gh-lol_AMDLIKO_2008.pdf
/home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/folder2/Tandge-Gh-lol_AMDLIKO_2008.pdf

The above is the output, which means the files are not being renamed, was facing same issue earlier, when I sorted this the mv copied files at one location, not in directories.
So help required, and thanks for the response!

Below is the script i ran, did not put the mv command since file and newfile are same files.

for file in $(find /home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/ -type f -name "*.pdf")
do
  echo $file 
  newfile="$(echo $file | sed 's/\(.*\)\(.*?\)_\(.*?\)_\(.*?\).pdf$/\4\3_\2_\1.pdf/')"
  echo $newfile
done

Hopefully this worked ....

for file in $(find /home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/ -type f -name "*.pdf")
do
  echo $file
    newfile="$(echo $file | sed 's/\(.*\)\/\(.*\)_\(.*\)_\(.*\).pdf$/\1\/\4_\3_\2.pdf/')"
  echo $newfile
done

Does it works for you also, as you expected ?!?!

its woking, will try on more files and let ypu know, thanks!!!!

---------- Post updated at 02:51 PM ---------- Previous update was at 12:59 PM ----------

The script is working, but I wanted to know since i want to rename the file from NAME_DAME_2008, is there any way I can restrict the script to change files only ending with a year.
Example.
If the name of a file is Benzene_AMBL_pod.pdf
The script should not work
but if name is Benzene_AMBL_2008.pdf
the output should be 2008_AMBL_Benzene.pdf

thanks

I hope this is what u wanted....

for file in $(find /home/smriti/Aquino_2008/Important_script_final_dec2008/rearrange_pdf_names/ -type f -name "*.pdf")
do
  echo $file
    newfile="$(echo $file | sed 's/\(.*\)\/\(.*\)_\(.*\)_\([0-9]...\).pdf$/\1\/\4_\3_\2.pdf/')"
  echo $newfile
done

yeah thanks a lot