如何在R语言中按指定规则批量重命名多文件夹中的图片
Solution for Batch Renaming Images in R
Got it, let's automate your image renaming task efficiently! Since you already have your file_list sorted by modification date, we just need to group the files by their tube number (the subfolder name), assign sequential image numbers, and generate the new filenames in your desired format. Here's how to do it step by step:
Step 1: Load Required Packages
We'll use stringr for string manipulation and dplyr for grouping and sequencing (these packages make the process cleaner, but we can also adapt this to base R if you prefer):
# Install packages first if you haven't already # install.packages(c("stringr", "dplyr")) library(stringr) library(dplyr)
Step 2: Process the File List
Convert your file_list into a structured data frame to easily extract tube numbers and assign image sequences:
# Convert file list to a data frame file_df <- tibble(old_path = file_list) %>% # Extract the tube number from the folder path (e.g., "1" from "CGS1/1/Snap_001.jpg") mutate(tube_num = str_extract(old_path, "(?<=CGS1/)\\d+(?=/)") %>% as.integer(), # Assign sequential image numbers within each tube group img_num = row_number(), .by = tube_num) %>% # Generate the new filename with 3-digit padding for tube and image numbers mutate(new_filename = paste("CGS1", str_pad(paste0("T", tube_num), 4, pad = "0"), str_pad(paste0("L", img_num), 4, pad = "0"), sep = "_") %>% paste0(".jpg"), # Define the new file path (this places files in the main CGS1 folder) new_path = file.path("CGS1", new_filename))
Step 3: Batch Rename Files
Now we can execute the renaming. You can use a base R loop or a cleaner purrr function:
# Option 1: Base R loop for(i in seq_along(file_df$old_path)) { file.rename(from = file_df$old_path[i], to = file_df$new_path[i]) } # Option 2: Using purrr (more concise, no explicit loop syntax) # install.packages("purrr") library(purrr) walk2(file_df$old_path, file_df$new_path, file.rename)
Key Details Explained:
- Tube Number Extraction: The regex
(?<=CGS1/)\\d+(?=/)targets the numeric subfolder name betweenCGS1/and the next slash, so it pulls exactly the tube number from each path. - Sequential Image Numbers:
row_number()with.by = tube_numensures each tube's images get numbered 1, 2, 3... independently, so tubes don't share numbering sequences. - 3-Digit Padding:
str_pad()converts single/double-digit numbers to 3 digits (e.g.,1becomes001), matching yourT001/L001format. - File Placement: If you want to keep files in their original subfolders instead of moving to the main
CGS1folder, change thenew_pathline to:new_path = file.path(dirname(old_path), new_filename)
Test with Your Sample Data:
If we plug in your sample file_list:
file_list <- c("CGS1/1/Snap_001.jpg", "CGS1/1/Snap_002.jpg", "CGS1/1/Snap_005.jpg", "CGS1/2/Snap_006.jpg", "CGS1/2/Snap_007.jpg", "CGS1/2/Snap_082.jpg")
The generated new_filename column will exactly match your desired output:
[1] "CGS1_T001_L001.jpg" "CGS1_T001_L002.jpg" "CGS1_T001_L003.jpg" [4] "CGS1_T002_L001.jpg" "CGS1_T002_L002.jpg" "CGS1_T002_L003.jpg"
Pro tip: Test this with a small set of copied files first to confirm everything works before renaming all 100+ images!
内容的提问来源于stack exchange,提问作者Novice_stat

