Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How do I rename 2009-08-2009-08-13 to 2009-08-$my_var_till_2009-08-13 for multiple files? The 2009-08-13 portion changes with respect to the date of the file, so I need a way to grab that part of the filename. Could I use basename somehow?

share|improve this question
on what OS? – John T Sep 21 '09 at 0:55
I am running this on a Linux OS – bisnez Sep 21 '09 at 0:59

If the file names are always in that date format, I think that something like this would work (in a script) - this is, of course, assuming that they are all in the same directory and '$my_var_till' is defined in the shell:


cd <name_of_target_directory>

for i in `ls`
    yyyy=`echo $i | awk -F- '{print $3}`'
    mm=`echo $i | awk -F- '{print $4}'`
    dd=`echo $i | awk -F- '{print $5}'`

    mv $i "$yyyy-$mm-$my_var_till-$yyyy-$mm-$dd"

if '$my_var_till' is not defined in the shell, you could take it as a command line argument (of course you might want to add some error checking with the argument):


<continue on with code from above>
share|improve this answer

mmv can help:

If you ever have to rename or move multiple files under Linux, then the mmv shell command will make your life easy. The mmv utility will also come in handy for copying multiple files, appending content of one file to other files, as well as for creation of links.

share|improve this answer

This script will rename any file with a name like

this: 2009-08-2009-08-13
to:   2009-08-${my_var_till}_2009-08-13

For example, if my_var_till="whatever", and filename="2009-08-2009-08-13", then the result will be:

mv "2009-08-2009-08-13" "2009-08-whatever_2009-08-13"

Files with names that are not in that format will be skipped.

Try this:



for f in *
    # test if file is proper format
    echo "${f}"|grep -E '^[0-9]{4}-[0-9]{2}-[0-9]{4}-[0-9]{2}-[0-9]{2}$'>/dev/null
    if [ $? -eq 0 ]; then
        n=$(echo ${f}|sed -r 's/^(.{8})(.{10})$/'"\1${my_var_till}_\2/")
        mv "${f}" "${n}"
share|improve this answer


obligatory 1-liner...

for i in `ls`;do echo $i | awk -F- '{print "mv "$1"-"$2"-"$3"-"$4"-"$5" "$1"-"$2"-""'"$my_var_till"'""-"$3"-"$4"-"$5}';done


my_var_till=somevalue  # can replace with $1 to use command-line arg to script
for i in `ls`
     do echo $i | awk -F- '{print "mv "$1"-"$2"-"$3"-"$4"-"$5" "$1"-"$2"-""'"$my_var_till"'""-"$3"-"$4"-"$5}'

you could also use the rename command and supply a Perl regex.

assuming your variable is a variable you have set in the shell, which is what I think you're asking.


rename 2009-08* 2009-08-%my_var_till%_*
share|improve this answer

You must log in to answer this question.