Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I want to rename multiple files in the same directory using Bash scripting. Names of the files are as follows:

file2602201409853.p
file0901201437404.p  
file0901201438761.p  
file1003201410069.p  
file2602201410180.p

I want to rename to the following format:

file2503201409853.p
file2503201437404.p  
file2503201438761.p  
file2503201410069.p  
file2503201410180.p

I was reading about the rename command, and try to do it this way, but it does nothing, I think I have questions about the syntax. Then I read that you can make a loop using the mv command as follows:

for file in cmpsms*2014*.p; do
    mv "$file" "${file/cmpsms*2014*.p/cmpsms25032014*.p}"
done

But I can not rename the files. What am I doing wrong?

share|improve this question
    
possible duplicate of How can I rename a lot of files using a regex? –  Kiwy Mar 26 at 14:09
1  
You can't have a pattern expression on the right hand side of a parameter expansion replacement expression. What did you expect to be where that * is? –  kojiro Mar 26 at 14:22
    
@Kiwy That question is about removing a portion of the file name. Ergo, highly doubtfully duplicate. –  Michael Kjörling Mar 26 at 14:41
    
Next time, please describe the file name changes you want to make (I had to look at this for a fair while before seeing the differences and similarities). Examples are good, but a description as well as examples is even better. –  Michael Kjörling Mar 26 at 14:43

4 Answers 4

up vote 3 down vote accepted

You were right to consider rename first. The syntax is a little strange if you're not used to regexes but it's by far the quickest/shortest route once you know what you're doing:

rename 's/\d{4}/2503/' file*

That simply matches the first 4 numbers and swaps them for the ones you specified.

And a test harness (-vn means be verbose but don't do anything) using your filenames:

$ rename 's/\d{4}/2503/' file* -vn
file0901201437404.p renamed as file2503201437404.p
file0901201438761.p renamed as file2503201438761.p
file1003201410069.p renamed as file2503201410069.p
file2602201409853.p renamed as file2503201409853.p
file2602201410180.p renamed as file2503201410180.p
share|improve this answer
    
Note that this is the Perl rename on Debian and derivatives (Ubuntu, Mint, …). On other Linux distributions, rename is a completely different file renaming tool (which Debian ships as rename.ul). –  Gilles Mar 26 at 20:33

If you find you do this sort of thing a lot, look up "rename.pl". It's a perl script, but allows you to simply feed it perl code (like a s/// expression), and it will do a mass rename based on that expression or code.

There's a basic version here: http://stackoverflow.org/wiki/Rename.pl but there are other versions floating around the net. It's been around for ages and ages and ages.

share|improve this answer
ptrn='file[0-9][0-9][0-9][0-9]2014[0-9][0-9][0-9][0-9][0-9].p'
path=/dir
( set -- "${path}/"${ptrn} ; for f ; do {
    echo "mv ${path}/${f} \
        ${path}/file25032014${f#2014}" 
} ; done )

This should do the trick. Note - I'm not in the habit of handing over mass mv commands - as written it's just an echo. You'll have to sort that out before it'll work.

share|improve this answer

This should do the trick:

for f in file*; do mv $f ${f/${f:4:8}/25032014}; done

It replaces the string beween the 4th and the 12th character with "25032014".

share|improve this answer
    
this for f in file*; do mv $f ${f/${f:4:4}/2503}; done also work. –  Avinash Raj Mar 26 at 16:36

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.