在批量重命名路径中的文件时遇到问题。
这是我的问题: 我的驱动器大约有16000个或更多的文件(所有图像,但可能是.psd,.jpg,.ai,.png等)以非常混乱的方式散布在周围,但文件名幸运的是所有独特的,但是由于对于纯粹的数量,我无法肯定地说(我的意思是可能有2个文件名为abc.ai或等价,但不是很多)。我不知道路径,因为提供的csv只包含原始文件名,以及它们应该重命名为什么。
基本上,csv中的第一行是:
qwerty.jpg,asdfg.jpg
或
123-asd_qwe.ai,abcfgd.ai。
我确实尝试了几种解决方案; sed,一些脚本,我可以尝试的任何我真正做过的事。
我真的很想听到命题或想法,甚至是解决方案!
要注意:我试过::
sed 's/"//g' names.csv | while IFS=, read orig new; do echo mv "$orig" "$new"; done
和
sed 's/^/mv -i -v "/;s/, /" "/;s/$/";/' < names.csv | bash -
和
#!/bin/bash
while read line
do
OldImageName=${line%,*}
NewImageName=${line#*,}
mv "$OldImageName" "$NewImageName"
done <"names.csv"
答案 0 :(得分:2)
如果您完全确定names.txt
在oldname,newname
的顺序中具有名称的方式,则以下逻辑应该足够: -
#!/bin/bash
while read line
do
# Splitting the line with delimiter as ',' and
# getting the fields before and after
OldImageName=$(echo $line | cut -d "," -f 1)
NewImageName=$(echo $line | cut -d "," -f 2)
if [ $(find . -name "$OldImageName" | wc -l) -gt 0 ]; then
# Get the absolute path of the file
path=$(dirname $(readlink -f "$OldImageName"))
# Verbose option '-v' for verifying the file rename and
# to suppress errors if file not present
mv -v "$path/$OldImageName" "$path/$NewImageName" 2>/dev/null
fi
done <names.csv
答案 1 :(得分:1)
(在评论中澄清问题后重写了答案)。
只有当您的CSV包含整个路径而不仅仅是基本名称时,第一个解决方案才有效。您需要遍历它,找到每个文件并重命名。
sed -r 's/, ?/\t/' names.csv | while IFS=$'\t' read orig new; do
find $DIR -type f -name "$orig" | while read path; do
dirname=`dirname "$path"`
target_path="$dirname/$new"
if [[ ! -f "$target_path"]]; then
mv -v -- "$path" "$target_path"
else
echo "Could not rename '$path' to '$target_path'. Target file exists" >&2
fi
done
done
将$DIR
替换为最顶层的目录。注意我假设每个基本名称可能与不同目录中的许多文件相对应。这就是我遍历find
。
答案 2 :(得分:0)
这是在上述特定情况下工作的完整解决方案 - 它需要考虑重复文件(在不同文件夹中),并且文件名(空格,重音等)的命名不会影响脚本。请参阅以下解决方案:
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
while read line
do
OldImageName=$(echo $line | cut -d "," -f 1)
NewImageName=$(echo $line | cut -d "," -f 2)
isMatchRelativePath=$(echo $(find . -name "$OldImageName"));
isMatchNewName=$(echo $(find . -name "$NewImageName"));
if [ ! -z "$isMatchRelativePath" ];
then
find . -name "$OldImageName" -print0 | while read -d $'\0' file
do
relativeFolder="${file%$OldImageName}"
quote1="$relativeFolder$OldImageName";
quote2="$relativeFolder$NewImageName";
mv "${quote1}" "${quote2}"
echo "$relativeFolder$OldImageName, $relativeFolder$NewImageName">>"$DIR/success.csv"
done
elif [ ! -z "$isMatchNewName" ]; then
echo "alreadyRenamed"
echo "$relativeFolder$OldImageName, $relativeFolder$NewImageName">>"$DIR/alreadyRenamed.csv"
else
echo "failed"
echo "$relativeFolder$OldImageName, $relativeFolder$NewImageName">>"$DIR/failed.csv"
fi
done <input.csv