Batch file renaming in Linux commandline with bash

Bash

We all have experienced it once (or more) times in our life. You have a huge list of filenames and you want to (or have to) rename all those files. You could do it manually one by one but since we are lazy we only want to have a command to fix this for us. We will show you in this article how to bulk rename your files in the Linux commandline.

Batch appending filenames

Lets assume we have a folder of jpg images and we want to append something at the end of the filename. In this example we have the files ‘testimage.jpg’, ‘testimage1.jpg’ etc. We want this to change into ‘testimage_hexample.jpg’, ‘testimage1_hexample.jpg’ and so on. The first thing we have to do is to copy all the images on which we want to apply this structure into an empty folder. Next cd into this folder and execute the following line:

for i in *; do j=`echo $i | cut -d . -f 1`; r=$j"_hexample.jpg"; mv $i $r; done

Let’s analyze this command:

  • for i in *: for every item in this folder
  • do j=`echo $i | cut -d . -f 1`: j=the first part of the echoed filename which is cut by the delimiter ‘.’. So the first part of ‘testimage.jpg’ cut by the delimeter ‘.’ is ‘testimage’.
  • r=$j”_hexample.jpg”: the variable r contains the name (testimage in this case) and appends ‘_hexample.jpg’ to it.
  • mv $i $r: replace the filename, which was stored in $i, with the new filename, which was stored in $r
  • done: End the command.

But as you can see, there is a problem with this. The above line only works for renaming .jpg files. But what if we have a folder with mixed extensions? Don’t worry, we will teach you how to rename your files with mixed extensions.

Batch renaming files with mixed extensions

To rename our files with mixed extensions we only need to change a few things in our previous command so it becomes:

for i in *; do j=`echo $i | cut -d . -f 1`; e=`echo $i | cut -d . -f 2`; j=$j"_hexample."$e; mv $i $j; done

We added the e=`echo $i | cut -d . -f 2`; part. This will store the extension in a new variable named $e. The other thing we edited is the j= part. We changed it to j=$j”_hexample.”$e;. What this will do is add the original extension to the new filename. It’s as simple as that!

Batch renaming files in ordered numbers

Say that we don’t care what our filenames are but we want them to give them numbers from 0 untill 99 for example (if we have 100 files in our folder). So we will change our filenames ‘randomimagename.jpg’, ‘randomnameofimage.gif’,… to ’1.jpg’, ’2.gif’,…. To do this we use the following line:

new=0 ; ext= ; for i in *; do ext=${i#*.}; mv $i $new.$ext; ((new++)); done;

Let’s analyze this line again:

  • new=0: Set the variable new to 0.
  • ext=: Set the variable ext to empty.
  • for i in *: For every file in the folder.
  • do ext=${i#*.}: Set the variable ext to the extension of the filename.
  • mv $i $new.$ext: Rename the original filename with the new filename (the number) and it’s original extension.
  • ((new++)): Increase the variable new with one.
  • done: End the command.

Note that we could also use ext=${i#*.} in the previous example to get the extension. But we just wanted to show different ways. One remark though, if you use the ext=${i#*.} you need to make sure that your filenames are without spaces.

Batch rename files to their modification date

Let’s assume we want to keep order in our files and that we want to change our filenames to the date they were last modified. To do this we make use of the ‘date’ command like this:

ext= ; for i in *; do ext=${i#*.}; timestamp=`date -r $i +%F_%X`; mv $i $timestamp.$ext; done;

The only thing special here is the ‘date -r $i +%F_%X’ command. The -r is for getting the last modification date of the file $i. Further is the %F is to get the full date notation in %Y-%m-%d. The %X is for the time notation.

These were some examples on how to rename your files in Linux. If you have other questions regarding this matter, please post them in the comments and we will try to solve them.

Tags: , ,

6 Responses to Batch file renaming in Linux commandline with bash

  1. NikYas

    I have 2 questions. The first one regarding 2 last cases: why do we need to set variable ext to empty? The second: can you explain in more detail part “ext=${i#*.}”, it isn’t clear for me.

    Thank you in advance.

  2. Sid

    Great article! I’m trying to use your last example to prepend the modification date to the existing file name for indexing purposes. What changes to your script do I need to make. Thanks!

  3. Mike Dziedzic

    Wow! Thank you! This is exactly what I needed, and your explanations are very clear and helpful.

  4. laurent B

    Thanks a lot for this post, this is was I was looking for…
    I have plenty of files called *.1 *.2 *.3 … *.10 *.11 … *.100 *.101
    and I renamed them as *.001 *.002 …………. *.101

    probably not the best way of doing it but here is the solution in 2 steps:
    for i in *.?; do j=`echo $i | cut -d . -f 1`; e=`echo $i | cut -d . -f
    2`; j=$j”.00″$e; mv $i $j; done

    for i in *.??; do j=`echo $i | cut -d . -f 1`; e=`echo $i | cut -d . -
    f 2`; j=$j”.0″$e; mv $i $j; done

    Thanks again.
    Laurent

  5. joseph gichira

    I want to change the filename in a batch as follows. to change a file from MEN30.txt to MENMT.txt. I have several such files in a particular directory and the only different thing in them is the numeral e.g. 30

    Any advice please

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>