问题
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
回答1:
This has been asked: Recursive batch rename
With your example, you could go with:
brew install rename
find . -exec rename 's|foo|bar|' {} +
回答2:
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.
回答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.
来源:https://stackoverflow.com/questions/16935127/rename-files-recursively-mac-osx