48

Is there any way of batch renaming files in sub directories?

For example:

Rename *.html to *.htm in a folder which has directories and sub directories.

jww
  • 97,681
  • 90
  • 411
  • 885
Shoban
  • 22,920
  • 8
  • 63
  • 107
  • By batch, do you mean "lot at a time" or in a .bat/.cmd/.sh way? The former isn't a programming question, and on Windows, there are tons of free utilities for that. The latter need more precision, at least which OS you target. – PhiLho Oct 29 '08 at 06:27

11 Answers11

99

Windows command prompt: (If inside a batch file, change %x to %%x)

for /r %x in (*.html) do ren "%x" *.htm

This also works for renaming the middle of the files

for /r %x in (website*.html) do ren "%x" site*.htm
Brian Webster
  • 30,033
  • 48
  • 152
  • 225
Anonymous
  • 3,388
  • 1
  • 17
  • 4
  • 2
    Notably, this also works for renaming just the middle part of the file. So, if all your files started with website... and ended with .html, and you wanted to rename them to start with site as well as changing the extension, you could do: `for /r %x in (website*.html) do ren "%x" site*.htm` – jonnybot Oct 30 '13 at 02:40
  • Raven, try putting directories into double quotes. This should fix your problem. Linux escape spaces with backslash to fix that kind of situation and I think Windows has also something of that kind but I can't tell what character for sure. – 猫IT Jul 24 '18 at 08:30
  • I have to Remove .$$$ extension from files simply I write for /r %x in (*.$$$) do ren "%x" *. – Faraz Ahmed Jan 27 '20 at 10:43
6

If you have forfiles (it comes with Windows XP and 2003 and newer stuff I think) you can run:

forfiles /S /M *.HTM /C "cmd /c ren @file *.HTML"
Kim
  • 4,080
  • 2
  • 30
  • 51
BBX
  • 61
  • 1
  • 1
6
find . -regex ".*html$" | while read line;
 do 
    A=`basename ${line} | sed 's/html$/htm/g'`;
    B=`dirname ${line}`;
    mv ${line} "${B}/${A}";
 done
Aditya Mukherji
  • 9,099
  • 5
  • 43
  • 49
6

In python

import os

target_dir = "."

for path, dirs, files in os.walk(target_dir):
    for file in files:
        filename, ext = os.path.splitext(file)
        new_file = filename + ".htm"

        if ext == '.html':
            old_filepath = os.path.join(path, file)
            new_filepath = os.path.join(path, new_file)
            os.rename(old_filepath, new_filepath)
monkut
  • 42,176
  • 24
  • 124
  • 155
5

In Bash, you could do the following:

for x in $(find . -name \*.html); do
  mv $x $(echo "$x" | sed 's/\.html$/.htm/')
done
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
3
In bash use command rename :)

 rename 's/\.htm$/.html/' *.htm

 # or

 find . -name '*.txt' -print0 | xargs -0 rename 's/.txt$/.xml/'

 #Obs1: Above I use regex \. --> literal '.'  and  $ --> end of line
 #Obs2: Use find -maxdepht 'value' for determine how recursive is
 #Obs3: Use -print0 to avoid 'names spaces asdfa' crash!
2

I'm sure there's a more elegant way, but here's the first thing that popped in my head:

for f in $(find . -type f -name '*.html'); do 
    mv $f $(echo "$f" | sed 's/html$/htm/')
done
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
albertb
  • 2,874
  • 1
  • 20
  • 16
1

On Linux, you may use the 'rename' command to rename files in batch.

ayaz
  • 10,406
  • 6
  • 33
  • 48
1

there is pretty powerfull forfiles command:

forfiles /? gives u hint of what is possible with the command. in this case it can be used like:

forfiles /S /M *.html /C "cmd /c rename @file @fname.htm"
vilem cech
  • 123
  • 7
0

AWK on Linux. For the first directory this is your answer... Extrapolate by recursively calling awk on dir_path perhaps by writing another awk which writes this exact awk below... and so on.

ls dir_path/. | awk -F"." '{print "mv file_name/"$0" dir_path/"$1".new_extension"}' |csh
Alex
  • 8,521
  • 6
  • 31
  • 33
0

On Unix, you can use rnm:

rnm -rs '/\.html$/.htm/' -fo -dp -1 *

Or

rnm -ns '/n/.htm' -ss '\.html$' -fo -dp -1 *

Explanation:

  1. -ns : name string (new name). /n/ is a name string rule that expands to the filename without the extension.
  2. -ss : search string (regex). Searches for files with match.
  3. -rs : replace string of the form /search_regex/replace_part/modifier
  4. -fo : file only mode
  5. -dp : depth of directory (-1 means unlimited).
Jahid
  • 21,542
  • 10
  • 90
  • 108