在路径中对文件进行大规模重命名时出现问题。
这是我的问题:我有一个大约16000或更多的文件驱动器(所有的图像,但可能是.psd,.jpg,.ai,.png等)散落在一个非常混乱的方式,但文件名是唯一的,但由于数量巨大,我不能肯定(我的意思是,可能有2个文件名为abc.ai或类似的,但不多)。我不知道路径,因为csv只包含原始文件名,以及它们应该重命名为什么。
基本上,csv的第一行是这样的:
qwerty.jpg,asdfg.jpg
或
123-ASDqwe.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"发布于 2016-05-19 12:49:16
这是在上面描述的特定情况下工作的完整解决方案--它考虑了重复的文件(在不同的文件夹中),并且文件名的命名(空格、重音等)也不影响脚本。见下文的解决办法:
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发布于 2016-04-26 09:55:10
如果您完全确定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发布于 2016-04-26 10:29:58
(在评论中澄清了问题后重写了答案)。
第一种解决方案只有在CSV包含整个路径时才能工作,而不仅仅是basenames。您需要遍历它,查找每个文件并重命名它。
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替换为最上面的目录.注意:我假设每个basename可能对应于不同目录中的许多文件。这就是我迭代find输出的原因。
https://stackoverflow.com/questions/36860923
复制相似问题