如何在 Linux Shell 中通过删除特殊字符而不使用重命名来批量重命名文件

如何在 Linux Shell 中通过删除特殊字符而不使用重命名来批量重命名文件

例如,我有 100 个文件,它们的名称都有空格。其中一个是“ The Monkey King Return (2015).mkv”。

如何删除名称中的所有空白并用点字符替换,同时删除“(”和“)”?

结果应为“ The.Monkey.King.Return.2015.mkv”。

我如何才能批量执行此操作?

我实际上是通过 ssh 在 Synology NAS 中运行 shell 脚本,这是一个安装了 bash 和 ash 的 BusyBox Linux 发行版,没有 gcc。已经尝试了几天,但无法正确弄清楚。

可用工具:mv / xargs / sed / awk / 其他标准 linux cmd。

另外如何递归地对子文件夹进行重命名?

编辑:刚刚使用 Debian Chroot 将 apt-get 和重命名 cmd 安装在我的 synology nas 中https://synocommunity.com/,所以现在没问题了。

为了让需要简单答案的人,cmd 是:

find . -iname \*\ \*.\*|rename 's/\ /\./g'

答案1

大多数 Linux 发行版都包含util-linux它为您提供rename命令。您可以通过运行以下命令来执行您的请求:

rename ' ' _ *.mkv
rename '(20' 20 *.mkv
rename ').' . *.mkv

您可以尝试使用这些选项,它非常灵活。如果您想以递归方式执行此操作,请rename与 find 命令结合使用,如下所示:

find . -type f -name \*.mkv -exec rename ' ' _ {} \;

这些在手册中有说明;输入man findman rename阅读它们。


请注意,某些发行版显然包含接受 perl 正则表达式的不同命令。如果您的发行版也包含接受 perl 正则表达式的命令,则需要稍微不同的语法:

rename 's/\ /./g' *.mkv
rename 's/[\)\(]//g' *.mkv

答案2

如果你没有该rename命令,你可以用一个小的 shell 脚本来执行此操作,busyboxash似乎也支持该脚本(这是递归的):

find -type f -name \*.mkv | while read f; do
    n=${f/ /_} # replace spaces
    n=${n/(/}  # remove opening bracket
    n=${n/)/}  # remove closing bracket

    mv -v "$f" "$n"
done

请注意,如果文件夹名称还包含空格或括号,则会中断。

答案3

我使用这一行代码删除字幕文件中的无效字符:

for f in *.srt; do nf=$(echo "$f" |sed -e 's/[^A-Za-z0-9.-]/./g;s/\.\.\././g;s/\.\././g'); test "$f" != "$nf" && mv "$f" "$nf" && echo "$nf"; done
  1. 仅处理 *.srt 文件(* 可以代替 *.srt 来处理每个文件)
  2. 删除除字母 A-Za-z、数字 0-9、句点“.”和破折号“-”之外的所有其他字符
  3. 删除可能出现的双重或三重句号
  4. 检查文件名是否需要更改
  5. 如果为真,则使用 mv 命令重命名文件,然后使用 echo 命令输出所做的更改

它用于规范电影的目录名称:

for f in */; do nf=$(echo "$f" |sed -e 's/[^A-Za-z0-9.]/./g' -e 's/\.\.\././g' -e 's/\.\././g' -e 's/\.*$//'); test "$f" != "$nf" && mv "$f" "$nf" && echo "$nf"; done

与上述步骤相同,但我添加了一个 sed 命令来删除目录末尾的句点

X战警:逆转未来 (2014) [1080p]
修改为:
X-Men.Days.of.Future.Past.2014.1080p

答案4

我一直在寻找这个问题的解决方案。我使用的是旧的封闭系统,无法安装新软件包。我没有命令rename。最后我写了一个脚本,它似乎适用于所有键盘输入的特殊字符:~@#$%^&*()-_=+[]{}\|;:",<.>?'

该脚本将重命名当前目录中的每个文件和目录。它将替换除字符之外的所有特殊字符-_._如果outfile=需要,可以修改该行以使用其他字符进行替换。例如,替换|_||.|以使用字符。.

#!/bin/bash

for file in ./*
do
  infile=`echo "${file:2}"|sed  \
         -e 's|"\"|"\\"|g' \
         -e 's| |\ |g' -e 's|!|\!|g' \
         -e 's|@|\@|g' -e 's|*|\*|g' \
         -e 's|&|\&|g' -e 's|]|\]|g' \
         -e 's|}|\}|g' -e 's|"|\"|g' \
         -e 's|,|\,|g' -e 's|?|\?|g' \
         -e 's|=|\=|g'  `
  outfile=`echo "${file:2}"|sed -e 's|[^A-Za-z0-9._-]|_|g'`
  mv "$infile" ${outfile} &
done

exit

相关内容