递归重命名与正则表达式匹配的子目录

递归重命名与正则表达式匹配的子目录

我有一个媒体服务器,其中有一个名为 的文件夹Series。 ( /media/Expansion2/Series/)

里面有(惊喜!)电视剧。这些只是节目名称,例如,/media/Expansion2/Series/The Big Bang Theory/

在每个节目的文件夹中(这就是问题所在)我有季节文件夹。我目前混合了以下两种约定(可能还有其他一些约定):

  1. /media/Expansion2/Series/The Big Bang Theory/The Big Bang Theory Season 1
  2. /media/Expansion2/Series/The Big Bang Theory/Season 2

最后,我想将所有文件夹重命名为Season #.

作为正则表达式,我可能会说类似的话s/.*(Season \d)/$1

仅适用于文件夹,不适用于文件。我可能还应该提到,这适用于大约 50 多个显示子文件夹,因此需要从该/media/Expansion2/Series/级别开始并查看每个系列:)

答案1

在 Debian 及其衍生版本(包括 Ubuntu)上:

find /media/Expansion2/Series/ -type d -exec rename -n 's/.*(Season \d)/$1/' {} ";"

rename命令是 Perl 包的一部分。其他发行版没有提供它,而是提供了标准的 Linuxrename命令,但在这里没有用。

如果rename -n(-不是真的)显示它想要执行的操作,并且这对您来说没问题,则省略 -n 并使其发生。

答案2

以下代码片段将删除Season [0-9]下每个显示目录中最后一次出现之前发生的任何内容/media/Expansion2/Series。不需要正则表达式,只需 glob。

cd /media/Expansion2/Series
for show in ./*/; do
    (
        cd "$show" || { echo "cd failed.  Skipping $show"; exit 1; }
        for season in ./*Season\ [[:digit:]]*/; do
                season_prefix=${season%Season [[:digit:]]*}
                mv "$season" ./"${season#$season_prefix}"
        done
    )
done

答案3

如果您想安全起见,只重命名some show/some show stuffsome show/stuff

for d in */; do
  for f in "$d${d%/} *"; do
    mv "$f" "${d}${f%$d${d%/} }"
  done
done

如果你想删除之前的所有内容Season

for x in */*Season*; do
  mv "$x" "${x%/*}/${x##*Season}Season"
done

${var#PATTERN}去除开头的 PATTERN$var并返回结果。${var%PATTERN}最后做同样的事情。${var#PATTERN}分别${var%PATTERN}去除最短匹配的前缀和后缀;${var##PATTERN}${var%%PATTERN}删除最长的匹配项。

答案4

我将发布另外两个解决方案,希望它们对将来有所帮助。这些来自工作中的 Linux 管理员。只是为了展示有多少锤子可以敲这颗钉子!

解决方案一:

嗨德纳姆,

我必须在这里做出一些假设,例如目录中带有“XXX Season #”的部分将始终是“外部”目录(叶节点)。

无论如何,我都会写一个小脚本。像这样的东西应该可以工作(注意变量周围的双引号,以确保捕获目录中的所有空格):

find /media/Expansion2/Series/ -type d | while read olddir
do 
   newdir=`echo "${olddir}" | awk -F "/" '$NF ~ /Season/ { last=substr($NF,index($NF, "Season")); while (i<(NF-1)) { i++; printf("/%s", $i) }; printf("/%s\n", last) } $NF !~ /Season/ { print }'`
   if [ "${olddir}" != "${newdir}" ]
   then
       mv "${olddir}" "${newdir}"
   fi
done

当然,在使用命令“ mv "${olddir}" "${newdir}" "运行之前,您应该输入类似“ echo "${olddir}" "${newdir}" 的内容以确保您获得您期望的结果,否则您可能会再次头痛:-P


解决方案2:

嗨德纳姆,

大部分答案已经在问题中了。无论如何,从 Series 文件夹中运行类似以下内容应该可以正常工作:

find -mindepth 2 -maxdepth 2 -type d | while read dir; do mv -T "$dir" "`dirname "$dir"`/`basename "$dir" | sed "s/.*Season \([0-9]*\)$/Season \1/i"`"; done  


说明:
• find -mindepth 2 -maxdepth 2 -type d(列出向下两级的目录)
• while read dir; (在每个目录上循环)
• mv -T "$dir" (将源目录移动到... 如果季节文件夹不唯一,即您没有“The Big Bang Theory Season”,则需要 -T 才能收到错误22”和“Season 22”在同一目录中)
• dirname "$dir" 返回目录所在的路径
• basename "$dir" 返回目录的名称
• sed "s/.季节([0-9])$/Season \1/i" 使用不区分大小写的正则表达式完成了魔法,以防万一。

在我的小测试中它有效(首先在 mv 之前使用 echo 尝试):

someuser@linux-box:/tmp/Series$ find
.
./The Big Bang Theory
./The Big Bang Theory/Season 2
./The Big Bang Theory/Season 2/file1.avi
./The Big Bang Theory/Season 2/file 3.avi
./The Big Bang Theory/Season 2/file2.avi
./The Big Bang Theory/Season 2/file
./The Big Bang Theory/Season 2/3.avi
./The Big Bang Theory/The Big Bang Theory Season 1
./The Big Bang Theory/The Big Bang Theory Season 1/file1.avi
./The Big Bang Theory/The Big Bang Theory Season 1/file 3.avi
./The Big Bang Theory/The Big Bang Theory Season 1/file2.avi
./The Big Bang Theory/The Big Bang Theory Season 1/file
./The Big Bang Theory/The Big Bang Theory Season 1/3.avi
./Other Series
./Other Series/Season 2
./Other Series/Stre dsfdf sd dSeason 3

someuser@linux-box:/tmp/Series$ find -mindepth 2 -maxdepth 2 -type d | while read dir; do mv -T "$dir" "dirname "$dir"/basename "$dir" | sed "s/.*Season \([0-9]*\)$/Season \1/i""; done
mv: ./The Big Bang Theory/Season 2' and./The Big Bang Theory/Season 2' are the same file
mv: ./Other Series/Season 2' and./Other Series/Season 2' are the same file

someuser@linux-box:/tmp/Series$ find
.
./The Big Bang Theory
./The Big Bang Theory/Season 2
./The Big Bang Theory/Season 2/file1.avi
./The Big Bang Theory/Season 2/file 3.avi
./The Big Bang Theory/Season 2/file2.avi
./The Big Bang Theory/Season 2/file
./The Big Bang Theory/Season 2/3.avi
./The Big Bang Theory/Season 1
./The Big Bang Theory/Season 1/file1.avi
./The Big Bang Theory/Season 1/file 3.avi
./The Big Bang Theory/Season 1/file2.avi
./The Big Bang Theory/Season 1/file
./The Big Bang Theory/Season 1/3.avi
./Other Series
./Other Series/Season 3
./Other Series/Season 2

相关内容