我有一个.csv
文件,其中看起来像这样:
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
我已编写此代码,将字段1中的名称(例如unnamed_0711-42_p1.mov
)重命名为字段2中的名称(例如day1_0711-42_p1.mov
)。
csv=/location/rename.csv
cat $csv | while IFS=, read -r -a arr; do mv "${arr[@]}"; done
但是,此脚本仅在它和所有需要重命名的文件位于同一目录中时才有效。以前这没关系,但现在我需要在各个子目录中查找文件(不添加我的.csv
文件的完整路径)。
如何调整我的脚本以便搜索子目录中的文件,然后像以前一样更改名称?
答案 0 :(得分:1)
脚本
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
应该这样做。
请参阅[ find ]联机帮助页以了解printf说明符如%p,%h
答案 1 :(得分:1)
使这项工作的一种简单方法,虽然它会导致效率低下,但是:
for D in `find . -type d`
do
cat $csv | while IFS=, read -r -a arr; do mv "${arr[@]}"; done
done
这将为当前目录中的每个目录运行您的命令,但这会运行每个子目录的整个文件名列表。另一种方法是在处理它的名称时搜索每个文件:
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"
这使用find
找到每个旧文件名,然后使用dirname
获取旧文件的目录(我们需要这样,以便mv
不会将重命名的文件放入不同的目录)。
这将重命名每个文件的每个实例(即,如果unnamed_0711-42_p1.mov
出现在多个子目录中,则每个实例将重命名为day1_0711-42_p1.mov
)。如果你知道每个文件名只会出现一次,你可以通过在管道之前的find命令末尾添加-print -quit
来加快速度。