I have a .csv
file in which looks something like this:
unnamed_0711-42_p1.mov,day1_0711-42_p1.mov
unnamed_0711-51_p2.mov,day1_0711-51_p2.mov
unnamed_0716-42_p1_2.mov,day1_0716-42_p1_2.mov
unnamed_0716-51_p2_2.mov,day1_0716-51_p2_2.mov
I have written this code to rename files from the name in field 1 (eg unnamed_0711-42_p1.mov
), to the name in field 2 (eg day1_0711-42_p1.mov
).
csv=/location/rename.csv
cat $csv | while IFS=, read -r -a arr; do mv "${arr[@]}"; done
However, this script only works when it and all the files that need to be renamed are in the same directory. This was okay previously, but now I need to find files in various subdirectories (without adding the full path to my .csv
file).
How can I adapt my script so that is searches out the files in subdirectories then changes the name as before?
Below script
while IFS=, read -ra arr # -r to prevent mangling backslashes
do
find . -type f -name "${arr[0]}" -printf "mv '%p' '%h/${arr[1]}'" | bash
done<csvfile
should do it.
See [ find ] manpage to understand what the printf specifiers like %p,%h do
A simple way to make this work, though it leads to an inefficient script, is this:
for D in `find . -type d`
do
cat $csv | while IFS=, read -r -a arr; do mv "${arr[@]}"; done
done
This will run your command for every directory in the current directory, but this runs through the entire list of filenames for every subdirectory. An alternative would be to search for each file as you process it's name:
csv=files.csv
while IFS=, read -ra arr; do
while IFS= read -r -d '' old_file; do
old_dir=$(dirname "$old_file")
mv "$old_file" "$old_dir/${arr[1]}"
done < <(find . -name "${arr[0]}" -print0)
done<"$csv"
This uses find
to locate each old filename, then uses dirname
to get the directory of the old file (which we need so that mv
does not place the renamed file into a different directory).
This will rename every instance of each file (ie, if unnamed_0711-42_p1.mov
appears in multiple subdirectories, each instance will be renamed to day1_0711-42_p1.mov
). If you know each file name will only appear once, you can speed things up a bit by adding -print -quit
to the end of the find command, before the pipe.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.