9

How can I recursively replace a string in all folders and files' name with a different string? I am running Red Hat 6 and I can find them with:

find . -name \*string\*

I've managed to do it for strings within files:

find . -type f -exec sed -i 's/string1/string2/g' {} +

but how could I replace in a similar way all file names?

terdon
  • 242,166
Blasco
  • 264
  • how can I replace a string with the mv command? There might be different folders names containing that string. I would need something like "find . -type f -exec sed -i 's/string1/string2/g' {} +" but for folder names – Blasco Jan 10 '18 at 09:34
  • On what operating system? Do you have a rename command? Is it perl rename? – terdon Jan 10 '18 at 09:35
  • mv is the final tool. You need to start with find + bash/shell beforehand – RomanPerekhrest Jan 10 '18 at 09:35
  • 1
    The command you show (sed) doesn't change any file names. It replaces the string inside the file but leaves the file name as it was. – terdon Jan 10 '18 at 09:37
  • @terdon I'm using red had 6, I have the rename command – Blasco Jan 10 '18 at 09:38
  • @terdon yes, that's my problem, I've managed to change the string within all the files, but I would like to know how to replace the name of folders and files too – Blasco Jan 10 '18 at 09:38

3 Answers3

8

you can replace all the file names using for and mv command.

here i am replacing all the text files starting with abc names with xyz

for file in abc*.txt; do mv -v "$file" "${file/abc/xyz}"; done

the below command will replace the files recursively in all folders

for file in `find . -type f -name 'abc*.txt'`; do mv -v "$file" "${file/abc/xyz}"; done
Ganesh_
  • 181
8

Using find and rename:

find . -type f -exec rename 's/string1/string2/g' {} +

The find . -type f part of the command means to search for all files (-type f) in the current directory (.).

  • The -exec option tells find to execute a command on each file it finds.

  • The rename command is used to rename files, and the syntax used here is for the Perl version of rename.

  • The 's/string1/string2/g' is a regular expression that specifies what to search for and what to replace it with. In this case, string1 is the string to be replaced, and string2 is the replacement string. The /g at the end means to replace all occurrences of string1 in the filename.

  • The {} symbol is a placeholder for the filename that find has found.

  • The + at the end of the command tells find to pass multiple filenames at once to the rename command, which is more efficient than invoking rename for each individual file.

So, overall, this command searches for all files in the current directory and executes the rename command to replace all occurrences of string1 with string2 in the filename for each file found.

AdminBee
  • 22,803
PesaThe
  • 583
  • 3
  • 7
  • This is nice! Please keep in mind that there are some cases with deeper direction structures. For flat directory changes this is fine. – gies0r Jan 15 '19 at 12:24
2

It's easier with zsh's zmv:

autoload zmv # best in ~/.zshrc
zmv '(**/)(*string1*)' '$1${2//string1/string2}'

Change to

zmv '(**/)(*string1*)(#qD)' '$1${2//string1/string2}'

If you also want to rename hidden files or files in hidden directories.