Go Back   The UNIX and Linux Forums > Top Forums > UNIX for Dummies Questions & Answers


UNIX for Dummies Questions & Answers If you're not sure where to post a UNIX or Linux question, post it here. All UNIX and Linux newbies welcome !!

Closed Thread    
 
Thread Tools Search this Thread Display Modes
    #1  
Old 02-24-2012
Registered User
 
Join Date: Feb 2012
Posts: 1
Thanks: 4
Thanked 0 Times in 0 Posts
Power Bash script to rename files in a directory

Dear friends,

I have created a script to rename all files in a directory by appending the file name with username (who created the file), the date it was created. For example, "apple.doc" should be renamed to "johnFeb23apple.doc" where "john" is the owner and "Feb23" is file created date. It works fine with file names without spaces. but there are few issues I don't know how to fix.

First, Here's my script:


Code:
#!/bin/bash
for i in *
do
newname=$(ls -l ${i} | awk '{ print $3 $6 $7 $9 }')

    mv $i $newname
done

1. When it met a file with spaces, e.g. like "fff eee.xls" it gives the following error and won't rename that file:


Code:
ls: cannot access fff: No such file or directory
ls: cannot access eee.xls: No such file or directory
mv: cannot stat `fff': No such file or directory


2. I need to run this script in the parent directory (it's sub directory contains all files to be renamed). How do I make that change in my script? (adding path of sub directory where all files stored)

script is in "/tommy/" directory and files in "/tommy/data/" directory

Please help me. Thanks in advance...

Last edited by DukeNuke2; 02-24-2012 at 02:00 PM..
Sponsored Links
    #2  
Old 02-24-2012
Mead Rotor
 
Join Date: Aug 2005
Location: Saskatchewan
Posts: 16,407
Thanks: 492
Thanked 2,538 Times in 2,421 Posts
You didn't quote the ${i} variable, so it split. Quote it "${i}"

Also, awk can't tell the difference between the spaces splitting the columns, and the spaces splitting the filename, causing problems.

Also, there's also no point running awk 9,000 times to process 9,000 lines. That's like making 9,000 phonecalls to say 9,000 words. awk can do it all in one go if it can do it at all.

But, I think shell read is better suited, since you can tell it exactly how many columns you want, and it won't split beyond that. Try and put 12 values into 9 columns, the last few columns will all get piled into the last variable unmodified. I really wish you could do that in awk, sometimes.


Code:
#!/bin/sh

cd /path/where/I/want/it/to/go

# The filename will get all put into the last variable, I
ls -l | while read A B C D E F G H I
do
        # Remove the 'echo' once you've tested it and found it does what you want.
        echo mv "$I" "$C$F$G$I"
done

The Following User Says Thank You to Corona688 For This Useful Post:
djsnifer (02-24-2012)
Sponsored Links
    #3  
Old 02-24-2012
Registered User
 
Join Date: Oct 2010
Location: Southern NJ, USA (Nord)
Posts: 3,806
Thanks: 8
Thanked 469 Times in 449 Posts
If you do not quote the white space, "$name" every reference, you need to use line feed as your delimiter, or if you have embedded linefeeds, more extreme tricks, like keying off the 'ls -l' non-name printout to pile up the right number of lines, tricky at EOF where there is no following line with an 'ls -l' prefix. C, PERL and such can handle each file name as one string without looking inside.
Code:
$ mkdir emb-ws
$ cd emb-ws
$ echo 'a space' >'a space'
$ echo 'two  space' >'two  space'
$ echo 'a   tab' >'a   tab'
$ echo 'a^Mcarriage-return' >'a^Mcarriage-return'
$  echo 'a
linefeed' >'a
linefeed'
$ ls | while read f; do   echo ">$f<"; done | cat -vte
> )
>a^Itab<$
>a<$
>linefeed<$
>a^Mcarriage-return<$
>a space<$
>two  space<$
$ ls -l |cat -vte
total 20$
-rw-rw-r-- 1 dpickett dpickett  6 Feb 24 15:09 a^Itab$
-rw-rw-r-- 1 dpickett dpickett 11 Feb 24 15:09 a$
linefeed$
-rw-rw-r-- 1 dpickett dpickett 18 Feb 24 15:09 a^Mcarriage-return$
-rw-rw-r-- 1 dpickett dpickett  8 Feb 24 15:09 a space$
-rw-rw-r-- 1 dpickett dpickett 11 Feb 24 15:09 two  space$
$

The Following User Says Thank You to DGPickett For This Useful Post:
djsnifer (02-24-2012)
    #4  
Old 02-24-2012
Mead Rotor
 
Join Date: Aug 2005
Location: Saskatchewan
Posts: 16,407
Thanks: 492
Thanked 2,538 Times in 2,421 Posts
Quote:
Originally Posted by DGPickett View Post
Yes, the blanks gt you right at the:
Code:
for i in *

The shell expands * and then divides the string by white space into a sequence of values.
Incorrect, * doesn't split on spaces by itself. * would be pretty useless if it did shell expansion inside itself. The right filenames end up in the $i variable.

But he doesn't quote the $i variable, causing it to split later.
The Following User Says Thank You to Corona688 For This Useful Post:
djsnifer (02-24-2012)
Sponsored Links
    #5  
Old 02-24-2012
Registered User
 
Join Date: Oct 2010
Location: Southern NJ, USA (Nord)
Posts: 3,806
Thanks: 8
Thanked 469 Times in 449 Posts
Yes, I misspoke, and edited it back a bit. Life can get crazy if you have recursive evaluations, like with
Code:
for i in $(ssh -n hostx 'ls *')

, one of the many reasons I prefer the pipe
Code:
ssh -n hostx 'ls *' | while read i

The Following User Says Thank You to DGPickett For This Useful Post:
djsnifer (02-24-2012)
Sponsored Links
Closed Thread

Tags
awk, bash, rename

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
Bash script to rename all files within a folder... dranzer UNIX for Dummies Questions & Answers 2 12-05-2010 04:18 PM
Split and Rename files using Terminal and bin/bash mschpers UNIX for Dummies Questions & Answers 7 12-02-2010 04:58 PM
Rename many files in a directory ananthi_ku Shell Programming and Scripting 8 01-27-2010 07:23 AM
Simple BASH shell script to rename webcam jpg and copy into a new directory. robfindlay Shell Programming and Scripting 4 03-22-2009 01:10 AM
Hello - new here - bash script - need to rename and zip files. Aixia Shell Programming and Scripting 1 07-15-2008 02:48 PM



All times are GMT -4. The time now is 11:33 AM.