Mastering file manipulation is crucial for any developer, and Ruby offers elegant solutions for renaming files efficiently. This guide explores various techniques, from single-file renames to complex batch operations across directories.
Table of Contents
- Why Rename Files Programmatically?
- Renaming a Single File
- Renaming Files in the Same Directory
- Renaming Files Recursively Across Subdirectories
- Batch Renaming Files with Custom Logic
- Robust Error Handling
Why Rename Files Programmatically?
Manual file renaming becomes impractical when dealing with numerous files. Automation offers several advantages:
- Efficiency: Process hundreds or thousands of files quickly and accurately.
- Standardization: Enforce consistent naming conventions for improved organization.
- Version Control: Append timestamps or version numbers to track file iterations.
- Workflow Integration: Seamlessly integrate file renaming into larger data processing pipelines.
- Data Cleanup: Correct typos, remove unwanted characters, and enhance searchability.
Renaming a Single File
The simplest scenario involves renaming a single file. Ruby’s File.rename
method handles this directly:
old_path = "/path/to/old_file.txt"
new_path = "/path/to/new_file.txt"
begin
File.rename(old_path, new_path)
puts "File renamed successfully!"
rescue Errno::ENOENT
puts "Error: File '#{old_path}' not found."
rescue Errno::EEXIST
puts "Error: File '#{new_path}' already exists."
rescue => e
puts "An error occurred: #{e.message}"
end
Renaming Files in the Same Directory
To rename multiple files within the same directory, use Dir.glob
to select files matching a pattern:
directory = "/path/to/files"
pattern = "*.txt"
Dir.glob("#{directory}/#{pattern}") do |file|
new_filename = file.gsub(/.txt$/, "_modified.txt") #Example renaming logic
begin
File.rename(file, new_filename)
puts "Renamed: #{file} -> #{new_filename}"
rescue => e
puts "Error renaming #{file}: #{e.message}"
end
end
Renaming Files Recursively Across Subdirectories
For renaming files across subdirectories, use the `**` wildcard with `Dir.glob`:
directory = "/path/to/files"
pattern = "*.txt"
Dir.glob("#{directory}/**/#{pattern}") do |file|
new_filename = file.gsub(/.txt$/, "_modified.txt")
begin
File.rename(file, new_filename)
puts "Renamed: #{file} -> #{new_filename}"
rescue => e
puts "Error renaming #{file}: #{e.message}"
end
end
Batch Renaming Files with Custom Logic
For more complex scenarios, use a hash to map old filenames to new filenames:
directory = "/path/to/files"
renames = {
"file1.txt" => "new_file1.txt",
"file2.jpg" => "new_file2.jpg"
}
renames.each do |old_name, new_name|
old_path = File.join(directory, old_name)
new_path = File.join(directory, new_name)
begin
File.rename(old_path, new_path)
puts "Renamed: #{old_path} -> #{new_path}"
rescue => e
puts "Error renaming #{old_path}: #{e.message}"
end
end
Robust Error Handling
Always include comprehensive error handling to gracefully manage issues like files not found or existing files.