I have thousands of files with no specific extensions. What I need to do is to search for a sting in filename and replace with other string and further search for second string and replace with any other string and so on. I.e.: I have multiple strings to replace with other multiple strings. It may be like:

  • "abc" in filename replaced with "def" *** String "abc" may be in many files
  • "jkl" in filename replaced with "srt" *** String "jkl" may be in many files
  • "pqr" in filename replaced with "xyz" *** String "pqr" may be in many files

I am currently using excel macro to get the file names in excel and then preserving original names in one column and replacing desired in the content copied in other column. then I create a batch file for the same. Like:

rename Path\OriginalName1 NewName1
rename Path\OriginalName2 NewName2

Problem with the above procedure is that it takes a lot of time as the files are many. And As I am using excel 2003 there is limitation on number of rows as well. I need a script in batch like:

replacestr  abc with def
replacestr  pqr with xyz

in a single directory. Will it be better to do in unix script?

  • Any Commas or anything in the new or old file names that matter? – nerdwaller Nov 21 '12 at 15:04
  • No commas in filename. – shekhar Nov 21 '12 at 15:06
  • perl -pi -e 's;original;replacement;g' list of files to munge – vonbrand Jan 23 '13 at 19:19

If you can use Bash, then the following script should do what you want:


(( $# != 2 )) && exit 1

for f in *; do
  if [[ $f != $newf ]]; then
    mv "$f" "$newf"

It tries to replace filename with new string, if resulted filename doesn't match original, then it renames the file to resulted filename.

Usage, if saved as replacestr and given mode to be executed:

$ ./replacestr abc def

It will try to rename all. You can use [[ ! -f $f ]] to skip non-file. You can also wrap it in function and source it from your ~/.bashrc if you need this very often.

  • It is working fine. to rename all I simply created another script with multiple instances of $ ./replacestr ... ... – shekhar Nov 21 '12 at 17:04

Any script you use could be potentially dangerous, but this worked for me on a limited scale (I just touched about 15 files and did a quick csv of abc,123 \n def,456 - etc.

With that out of the way, I would make a quick backup, test this on a few, and then roll it out.

-The excel is exported to CSV with the format oldname,newname on each line
-You are in a bash shell.
-All in one directory
-They are all files (you can change the script to dirs by changing -type f to -type d

while read line
    IFS=',' read -a names <<< "${line}"
    for file in `find . -maxdepth 1 -type f -name "*${names[0]}*"`; do
        rename "s/${names[0]}/${names[1]}/" *
done < ${inputfile}

This will work from the current directory (find .) and only work on 1 level(-maxdepth 1), items easily changed. Hope that at least gets you on the right track.

The important thing is this maintains the rest of your file name and only replaces the input string with the output. So file 123abc123.null with input of abc,999 would result in 123999123.null.

Just make it executable with chmod +x nameofmyscript.sh and execute it with ./nameofmyscript.sh input/file/location.csv

  • Every time I am executing the code it is showing error like : line 9 C:Users....**<Path structure without backslash> **:No Such file or Directory. I am using GitBash – shekhar Nov 22 '12 at 6:51
  • This assumed you are in a bash shell, you are apparently in Windows... (assumption 2) So if you would like to try it, you'll need to be in a unix bash shell. – nerdwaller Nov 22 '12 at 6:52

Here's a nice howto. There are many recipies, and even a script. I hope you'll find what you're looking for.

Actually you should study Regular expressions for better understanding of the topic.

  • Thanks. As I said there is no specific extension and string to be replaced may be anywhere in the filename not at beginning or at end. Howto link didn't worked for me. – shekhar Nov 21 '12 at 15:21

In a Windows batch file:

@echo off
setlocal enabledelayedexpansion
set needle=%~1
set replace=%~2
pushd %3
for %%i in (*.*) do (
    echo %%i|findstr "%needle%"> nul && (set match=%%i&move /-Y "%%i" "!match:%needle%=%replace%!")

Example syntax: batchrename.bat "abc" "def" ".\bigfolder"

It works by changing the current directory if one is specified, traversing it using for (use the /R-flag to include subdirectories). It then pipes the filename into a findstr-command, which will compare it against a needle string. If a match is found, the line is printed, but suppressed by > nul. If no match is found, the errorlevel is set to one, after which && prevents execution of the remainder of the command.

The variable %%i is then copied into %match%, because the iterator form does not support substring replacement. Then, the filename is renamed by the move-command using an altered destination string !match:%needle%=%replace%!.

Note that typos or bugs might mess up your filenames. Use with caution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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