举个例子,假设我有一个包含这些文件夹的文件夹:
Universal 2023 02 15 Some Name
Universal 2023 02 15 Some Name and Words After
Sony Some Name 2023 02 15
Sony Some Name 2023 02 15 and Words After
Desired output
Some Name - 2023 02 15 - Universal
Some Name - 2023 02 15 - And Words After - Universal
Some Name - 2023 02 15 - Sony
Some Name - 2023 02 15 - and Words After – Sony
我为每个名称结构写了一个命令。
1。 « Universal 2023 02 15 Some Name » 将更名为: « 一些名字 - 2023 02 15 - 通用 » 使用此命令:
rename -v 's/([\s\S]+)\s((\d{4})\s(\d{2})\s(\d{2}))\s(([\s\S]+)\s([\s\S]+))/$6 - $2 - $1/g' *
« Universal 2023 02 15 Some Name and Words After » 将更名为: « 一些名字 - 2023 02 15 - 之后的话 - 通用 » 使用此命令:
rename -v 's/([\s\S]+)\s((\d{4})\s(\d{2})(\s)(\d{2}))\s((\w+)\s(\w+))\s([\s\S]+)/$7 - $2 - $10 - $1/g' *
« Sony Some Name 2023 02 15 » 将更名为: « 一些名字 - 2023 02 15 - 索尼 » 使用此命令:
rename -v 's/([\s\S]+)\s((\w+)\s(\w+))\s((\d{4})\s(\d{2})\s(\d{2}))/$2 - $5 - $1/g' *
rename -v 's/([\s\S]+)\s((\d{4})\s(\d{2})\s(\d{2}))\s(([\w]+)\s([\w]+))\s([\s\S]+)/$6 - $2 - $9 - $1/g' *
当我想重命名这些文件夹时,我必须将它们归类到单独的文件夹中并运行相应的命令,然后在完成后将它们全部放回同一个文件夹中。它很烦人。所以我想在 bash 中编写一个脚本,以避免将它们单独归档并使所有内容都从主文件夹开始。在 VS 代码中,除了重命名命令外,一切似乎都很好。 这条线是橙色的......意味着缺少一些东西但我不知道它是什么:
's/([\s\S]+)\s((\d{4})\s(\d{2})\s(\d{2}))\s(([\w]+)\s([\w]+))\s([\s\S]+)/$6 - $2 - $9 - $1/g'
我的剧本:
for i in $*/; do
# for Universal 2023 02 15 Some Name
if [[ "$i" =~ ([\s\S]+)\s((\d{4})\s(\d{2})\s(\d{2}))\s(([\s\S]+)\s([\s\S]+)) ]];
then
rename -v 's/([\s\S]+)\s((\d{4})\s(\d{2})\s(\d{2}))\s(([\s\S]+)\s([\s\S]+))/$6 - $2 - $1/g' *
# for Universal 2023 02 15 Some Name and Words After
elif [[ "$i" =~ ([\s\S]+)\s((\d{4})\s(\d{2})(\s)(\d{2}))\s((\w+)\s(\w+))\s([\s\S]+) * ]];
then
rename -v 's/([\s\S]+)\s((\d{4})\s(\d{2})(\s)(\d{2}))\s((\w+)\s(\w+))\s([\s\S]+)/$7 - $2 - $10 - $1/g' *
# for Sony Some Name 2023 02 15
elif [[ "$i" =~ ([\s\S]+)\s((\w+)\s(\w+))\s((\d{4})\s(\d{2})\s(\d{2})) ]];
then
rename -v 's/([\s\S]+)\s((\w+)\s(\w+))\s((\d{4})\s(\d{2})\s(\d{2}))/$2 - $5 - $1/g' *
# for Sony Some Name 2023 02 15 and Words After
else [[ "$i" =~ ([\s\S]+)\s((\w+)\s(\w+))\s((\d{4})\s(\d{2})\s(\d{2})) ]];
then
rename -v 's/([\s\S]+)\s((\d{4})\s(\d{2})\s(\d{2}))\s(([\w]+)\s([\w]+))\s([\s\S]+)/$6 - $2 - $9 - $1/g' *
fi
done
任何人都可以帮助我!!!!!!!!! 非常感谢! 马丁
试试这个 Shellcheck-干净的代码:
#! /bin/bash -p
sep_rx='[[:space:]]+'
part_rx='[^[:space:]]+'
company_rx=$part_rx
name_rx="${part_rx}${sep_rx}${part_rx}"
date_rx="[[:digit:]]{4}${sep_rx}[[:digit:]]{2}${sep_rx}[[:digit:]]{2}"
after_rx="${part_rx}(${sep_rx}${part_rx})*"
cdn_rx="^($company_rx)$sep_rx($date_rx)$sep_rx($name_rx)\$"
cdna_rx="^($company_rx)$sep_rx($date_rx)$sep_rx($name_rx)$sep_rx($after_rx)\$"
cnd_rx="^($company_rx)$sep_rx($name_rx)$sep_rx($date_rx)\$"
cnda_rx="^($company_rx)$sep_rx($name_rx)$sep_rx($date_rx)$sep_rx($after_rx)\$"
for d in */; do
dir=${d%/}
if [[ $dir =~ $cdn_rx ]]; then
company=${BASH_REMATCH[1]}
date=${BASH_REMATCH[2]}
name=${BASH_REMATCH[3]}
newdir="$name - $date - $company"
elif [[ $dir =~ $cdna_rx ]]; then
company=${BASH_REMATCH[1]}
date=${BASH_REMATCH[2]}
name=${BASH_REMATCH[3]}
words_after=${BASH_REMATCH[4]}
newdir="$name - $date - $words_after - $company"
elif [[ $dir =~ $cnd_rx ]]; then
company=${BASH_REMATCH[1]}
name=${BASH_REMATCH[2]}
date=${BASH_REMATCH[3]}
newdir="$name - $date - $company"
elif [[ $dir =~ $cnda_rx ]]; then
company=${BASH_REMATCH[1]}
name=${BASH_REMATCH[2]}
date=${BASH_REMATCH[3]}
words_after=${BASH_REMATCH[4]}
newdir="$name - $date - $words_after - $company"
else
printf 'ERROR: Failed to match: %s\n' "$dir" >&2
exit 1
fi
mv -v -- "$dir" "$newdir"
done
\s
、\S
和 \d
与 Bash 中的 =~
不一致,所以我使用可移植字符类代替(例如 [^[:space:]]
用于 \S
)。 rename
实用程序并非在所有系统上都可用,并且至少有两个非常不同的版本在流通,因此我使用了标准的 mv
实用程序。请参阅为什么 Debian/Ubuntu 上的重命名实用程序与其他发行版(如 CentOS)上的重命名实用程序不同?.