Rename multiple files, but only rename part of the filename in Bash

BashFile Rename

Bash Problem Overview


I know how I can rename files and such, but I'm having trouble with this.

I only need to rename test-this in a for loop.

test-this.ext
test-this.volume001+02.ext
test-this.volume002+04.ext 
test-this.volume003+08.ext 
test-this.volume004+16.ext 
test-this.volume005+32.ext 
test-this.volume006+64.ext 
test-this.volume007+78.ext 

Bash Solutions


Solution 1 - Bash

If you have all of these files in one folder and you're on Linux you can use:

rename 's/test-this/REPLACESTRING/g' *

The result will be:

REPLACESTRING.ext
REPLACESTRING.volume001+02.ext
REPLACESTRING.volume002+04.ext
...

rename can take a command as the first argument. The command here consists of four parts:

  1. s: flag to substitute a string with another string,
  2. test-this: the string you want to replace,
  3. REPLACESTRING: the string you want to replace the search string with, and
  4. g: a flag indicating that all matches of the search string shall be replaced, i.e. if the filename is test-this-abc-test-this.ext the result will be REPLACESTRING-abc-REPLACESTRING.ext.

Refer to man sed for a detailed description of the flags.

Solution 2 - Bash

Use rename as shown below:

rename test-this foo test-this*

This will replace test-this with foo in the file names.

If you don't have rename use a for loop as shown below:

for i in test-this*
do
    mv "$i" "${i/test-this/foo}"
done

Solution 3 - Bash

Function

I'm on OSX and my bash doesn't come with rename as a built-in function. I create a function in my .bash_profile that takes the first argument, which is a pattern in the file that should only match once, and doesn't care what comes after it, and replaces with the text of argument 2.

rename() {
	for i in $1*
	do
    	mv "$i" "${i/$1/$2}"
	done
}
Input Files
test-this.ext
test-this.volume001+02.ext
test-this.volume002+04.ext 
test-this.volume003+08.ext 
test-this.volume004+16.ext 
test-this.volume005+32.ext 
test-this.volume006+64.ext 
test-this.volume007+78.ext 
Command
rename test-this hello-there
Output
hello-there.ext
hello-there.volume001+02.ext
hello-there.volume002+04.ext 
hello-there.volume003+08.ext 
hello-there.volume004+16.ext 
hello-there.volume005+32.ext 
hello-there.volume006+64.ext 
hello-there.volume007+78.ext 

Solution 4 - Bash

Without using rename:

find -name test-this\*.ext | sed 'p;s/test-this/replace-that/' | xargs -d '\n' -n 2 mv

The way it works is as follows:

  1. find will, well, find all files matching your criteria. If you pass -name a glob expression, don't forget to escape the *.

  2. Pipe the newline-separated* list of filenames into sed, which will:

    a. Print (p) one line.

    b. Substitute (s//) test-this with replace-that and print the result.

    c. Move on to the next line.

  3. Pipe the newline-separated list of alternating old and new filenames to xargs, which will:

    a. Treat newlines as delimiters (-d '\n').

    b. Call mv repeatedly with up to 2 (-n 2) arguments each time.

For a dry run, try the following:

find -name test-this\*.ext | sed 'p;s/test-this/replace-that/' | xargs -d '\n' -n 2 echo mv

*: Keep in mind it won't work if your filenames include newlines.

Solution 5 - Bash

to rename index.htm to index.html

rename [what you want to rename] [what you want it to be] [match on these files]
rename .htm .HTML *.htm

renames index.htm to index.html It will do this for all files that match *.htm in the folder.

Solution 6 - Bash

thx for your passion and answers. I also find a solution for me to rename multiple files on my linux terminal and directly add a little counter. With this I have a very good chance to have better SEO names.

Here is the command

count=1 ; zmv '(*).jpg' 'new-seo-name--$((count++)).jpg'

I also do a live coding video and publush it to YouTube

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3115029View Question on Stackoverflow
Solution 1 - BashTim ZimmermannView Answer on Stackoverflow
Solution 2 - BashdogbaneView Answer on Stackoverflow
Solution 3 - BashJoe FlackView Answer on Stackoverflow
Solution 4 - Bashuser16785526View Answer on Stackoverflow
Solution 5 - BashJ WieseView Answer on Stackoverflow
Solution 6 - BashRogoitView Answer on Stackoverflow