Rename files recursively Mac OSX
Asked Answered
R

5

39

Attempting to rename a bunch of files.

I can rename any instances of foo with bar in the current directory with:

ls . | awk '{print("mv "$1" "$1)}' | sed 's/foo/bar/2' | /bin/sh

What can I add to make it recursive?

Edit/My solution

I don't know/understand this shell type stuff so I did it with some (pretty dirty) Ruby:

5.times do
  Dir["**/*"].each do |f|
    file_name = File.absolute_path f
    should_rename = file_name.include? "yolo"
    new_file_name = file_name.gsub("yolo", "#{@project_name}")
    File.rename(f, new_file_name) if (should_rename and File.exists? f)
  end
end
Rodge answered 5/6, 2013 at 8:34 Comment(0)
M
72

This has been asked: Recursive batch rename

With your example, you could go with:

brew install rename
find . -exec rename 's|foo|bar|' {} +
Menado answered 5/6, 2013 at 8:45 Comment(4)
You can also filter the set of files that will be replaced by name. For example I needed to recursively rename all *.java files to *.txt so I did it like so: find . -name "*.java" -exec rename 's|\.java|\.txt|' {} +Thieve
rename can be used with a glob too, for example rename "s/.html/.twig/gi" templates/**/*Bow
Works but there is a catch. It replaces the first occurrence. For example, if I want to remove all the "_" from a file example_file_name.jpg, it would rename it to examplefile_name.jpgWilcox
find . -exec rename 's|foo|bar|g' {} +Menado
G
27

The rename utility also provides a syntax that does not require knowledge of regex. Once you have installed the utility

brew install rename

The option -s will replace the first instance of foo by bar:

find . -exec rename -s 'foo' 'bar' {} +

And the option -S will replace all instances:

find . -exec rename -S '_' ' ' {} +

This is really the same solution that Marcel Steinbach provided above, just a different syntax.

Glean answered 18/10, 2016 at 12:44 Comment(0)
S
24

Nice, clean, zero-dependency (so no brew install rename or whatever) from this webpage (archived version).

In this sample case, I'm swapping from .js to .ts to move a project from vanilla javascript to typescript, so I want to rename everything from *.js to *.ts first.

find . -iname "*.js" -exec bash -c 'mv "$0" "${0%\.js}.ts"' {} \;

Voila. Done.


NOTE: The only gotcha is that you've got two "before" spots and one "after". That is, in my case, you've got two .js instances to change. One looks for the .js files then the other replaces that .js with .ts.

find . -iname "*.js" -exec bash -c 'mv "$0" "${0%\.js}.ts"' {} \;
   first before ^                   second before ^   ^ one after
Subject answered 24/9, 2020 at 20:55 Comment(0)
P
6

You can also recursively rename files using the Finder.

  1. Browse to the folder where the tree of items are that need renaming.
  2. Switch the Finder window to "List" view.
  3. Expand all subfolders. This can be done using the keyboard shortcuts: ⌘-A (Cmd-A, select all), → (Right Arrow key, expand folder).
  4. Repeat the ⌘-A, → commands until all subfolders are open and all files are selected.
  5. Right-click on one of the selected files, and choose "Rename xx Items..."
  6. Use the "Rename Finder Items:" panel that opens to replace, add, or format text as desired.
  7. Click "Rename"
Ponderable answered 13/4, 2020 at 19:25 Comment(3)
Not really recursive, I have a folder containing 57,000 items across 1000's of subfolders so this would be far from ideal.Samsara
This simple thing worked for me..my directly structure was 6 or 7 deep and multiple bouts of command A + right arrow helped select everything and rename. thanks for this!!Insanitary
You can also option+click on the twirl down arrow to open all subfolders at once.Millrace
D
3

The answer to "how do I do X recursively on some file structure" is almost always to use find. In this case maybe also in combination with a for loop. The following example would recursively loop over the files matching the pattern foo in the current directory.

thedir=./
for file in $(find $dir -type f -name foo); do
    # rename $file here
done

Depending on your desired renaming scheme and how you wish to express the renaming, the body of the loop will have different renaming command(s).

Simply renaming every file named foo to bar will result in one file bar and that is not what people usually want. The $file variable contains the relative path to the file, so differents bar's will have different paths.

Donnelldonnelly answered 5/6, 2013 at 8:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.