使用 bash,我如何批量重命名大量文件,我需要根据每个文件的现有名称和“上下文映射”为每个文件构造一个新名称 - 不知道还能叫它什么 - 名称碎片。
我有很多这样的文件:
001.jpg
003.jpg
004.jpg
007.jpg
...
和这样的地图:
001,white
003,grey
004,red
007,green
...
现在我想重命名所有文件,使 001.jpg 变成 001-white.jpg 等等。
我怎样才能做到这一点?
答案1
bash4:首先将映射读入数组
declare -A arr2
while IFS=, read -r -a arr; do
arr2[${arr[0]}]="${arr[1]}";
done < mapfile.txt
然后重命名
for f in [0-9][0-9][0-9].jpg; do
if [[ "${arr2[${f%.*}]+_}" ]]
then
mv -- "${f}" "${f%.*}"-"${arr2[${f%.*}]}"."${f##*.}";
else
mv -- "${f}" "${f%.*}"-default."${f##*.}";
fi
done
答案2
你可以简单地执行
join -t. -j1 <(tr , . < map) filelist | sed 's/\./-/' | paste filelist - | xargs -L1 mv
其中map
是上下文映射,filelist
是文件列表。连接将拆分.
并使用第一个字段作为连接值;两个列表都必须排序。 paste
然后将每一行filelist
与新生成的文件名粘合在一起,然后xargs
调用mv
每一行。
答案3
干得好:
for file in [0-9][0-9][0-9].jpg;do
name="${file%%.*}" # Remove extension
map="$(grep "$name" map_file | cut -d',' -f 2)"
echo mv "$file" "$name-$map".jpg
done
这假设“地图”位于文件中map_file
。在最新版本的 Bash 中,您还可以将此文件转换为关联数组并使用它以方便使用(而不是遍历map_file
要重命名的每个新文件)。
顺便说一下,这只是echo
命令mv
。当您觉得一切正常时,请删除 ,echo
以便真正进行重命名。
答案4
< map sed 's/\([^,]*\),\(.*\)/mv -- "\1.jpg" "\1-\2.jpg"/' | sh -x
(假设映射文件不包含"
、$
、反斜杠或反引号字符。