Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I've got some files like this:

database1-backup-01-01-2011.sql
database2-backup-01-01-2011.sql

...etc. I want to rename them to add AM, like this:

database1-backup-01-01-2011-AM.sql
database2-backup-01-01-2011-AM.sql

What's the most concise way to do that from the bash shell?

share|improve this question
add comment

4 Answers

up vote 12 down vote accepted

Another option:

for i in *.sql ; do
    mv -v $i ${i%.sql}-AM.sql
done

This loops through all the .sql files and renames them to end in -AM.sql instead.

PROTIP: Use $(command) instead of `command` in your scripts (and command-lines), it makes quoting and escaping less of a nightmare.

share|improve this answer
    
Nice - the most concise way so far. –  Nathan Long Mar 2 '11 at 14:50
add comment

Since a Perl script has been suggested, here's a Ruby script to do the same:

`ls *.sql`.split("\n").each do |filename|
  new_filename = filename.split('.').join('-AM.')
  `mv #{filename} #{new_filename}`
end
share|improve this answer
add comment

Using the Perl script version of rename:

rename 's/\.sql$/-AM$&/' *.sql

Using the util-linux-ng version of rename (but only if ".sql" only appears at the end of the filename):

rename .sql -AM.sql *.sql

Using mmv:

mmv '*.sql' '#1-AM.sql'
share|improve this answer
add comment

Try this little script:

#!/bin/sh

FILES=`ls *.sql`
for FILE in ${FILES}
{
    BASE=`basename ${FILE} .sql`
    mv ${FILE} ${BASE}-AM.sql
}

I just typed that from memory so if it doesn't work 100% don't blame me (i.e., back up your data first ;) )

How it works:

Collect all files into a variable (you could put this inside the for instead but I like to keep things easy to read):

FILES=`ls *.sql`

Loop through each file:

for FILE in ${FILES} { ... }

Get the filename without .sql:

BASE=`basename ${FILE} .sql`

Rename the file, adding -AM.sql to the base name:

mv ${FILE} ${BASE}-AM.sql
share|improve this answer
2  
You can remove the line FILES=`ls *.sql` and replace ${FILES} by *.sql, shell expansion will take care of finding the files. –  Lekensteyn Mar 2 '11 at 14:48
    
This isn't the most concise way, but I do appreciate the readability and explanation. If I'm going to do this from the command line, I'd rather type what chrish shows, but if I were saving it as a script, I'd definitely use your way for readability. –  Nathan Long Mar 2 '11 at 14:51
1  
@Matt Jenkins: the readability does not increase by adding another ls command. Keep it simple. By the way, I think the { are bashish, it's better to replace them by do and done: for ...; do ...; done –  Lekensteyn Mar 2 '11 at 14:53
1  
@Matt Jenkins: FILES=`ls *.sql` <-- there. Shell expansion is built-in, no need for this extra ls. –  Lekensteyn Mar 2 '11 at 14:56
1  
Well forgive me for writing portable code. ls.. is just one source of files that the script could handle; it would be trivial to change it to use, say, a predefined list of files, or command line arguements, by just editing this variable. No need to change the structure of the for if you want to put the script to another use. Isn't that the point of this site? To give answers that are of interest to the genral populace? If that means making your scripts a little more wordy and a little more understandable then I don't see a problem with ls.. as it implicitly shows what is being worked on. –  Majenko Mar 2 '11 at 15:01
show 4 more comments

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.