在linux中使用正则表达式重命名文件

ore*_*ani 45 regex terminal rename

我有一组名为的文件:

Friends - 6x03 - Tow Ross' Denial.srt
Friends - 6x20 - Tow Mac and C.H.E.E.S.E..srt
Friends - 6x05 - Tow Joey's Porshe.srt
Run Code Online (Sandbox Code Playgroud)

我想像下面那样重命名它们

S06E03.srt
S06E20.srt
S06E05.srt
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能在linux终端上完成工作?我已经安装了重命名但是U使用以下方法获得错误:

rename -n 's/(\w+) - (\d{1})x(\d{2})*$/S0$2E$3\.srt/' *.srt
Run Code Online (Sandbox Code Playgroud)

Tho*_*hor 61

你忘记了星号前面的一个圆点:

rename -n 's/(\w+) - (\d{1})x(\d{2}).*$/S0$2E$3\.srt/' *.srt
Run Code Online (Sandbox Code Playgroud)

在OpenSUSE,RedHat,Gentoo上你必须使用Perl版本rename.这个答案显示了如何获得它.在Arch上,调用包perl-rename.

  • OpenSUSE,RedHat,Gentoo不支持`rename`中的正则表达式 (6认同)
  • openSUSE使用`util-linux`包中的重命名,我没有找到任何提供`file-rename`,`prename`或`perl-rename`的包 - 只有工作解决方案是[使用cpan安装](http:// stackoverflow .com/a/32862278/1392034)对我来说. (3认同)

Jon*_*mar 12

真的很酷的小迪迪。查找+ perl + xargs + mv

xargs -n2使每行打印两个参数成为可能。当与Perl结合使用print $_(首先打印$ STDIN)时,它将成为一个功能强大的重命名工具。

find . -type f | perl -pe 'print $_; s/input/output/' | xargs -n2 mv
Run Code Online (Sandbox Code Playgroud)

perl -pe 'print $_; s/OldName/NewName/' | xargs -n2最终结果是:

OldName.ext    NewName.ext
OldName.ext    NewName.ext
OldName.ext    NewName.ext
OldName.ext    NewName.ext
Run Code Online (Sandbox Code Playgroud)

我的系统上没有rename现成的Perl 。


它是如何工作的?

  1. find . -type f 输出文件路径(或文件名...您在这里控制正则表达式要处理的内容!)
  2. -p打印正则表达式处理的文件路径,-e执行内联脚本
  3. print $_首先打印原始文件名(与无关-p
  4. -n2 每行打印两个元素
  5. mv 获取上一行的输入

  • 最后一个命令应更改为“xargs -d '\n' -n2 mv”,否则 xargs 会将文件名中的空格视为分隔符,从而导致错误或无意义地重命名文件。`-d '\n'` 参数指定换行符应被视为分隔符。GNU xargs 有“-d”参数,但对于那些没有的实现(即我使用的 FreeBSD),这可以在大多数环境中工作:“find . -类型 f | perl -pe '打印$_; s/输入/输出/' | sed 's/ /\\ /g' xargs -n2 mv` 通过使用 `sed` 来转义通过管道传输到 `xargs` 的输出中的所有空格。(也许不优雅。) (8认同)
  • @s.co.tt 将空格视为普通字符的更好方法可能是使用不同的分隔符字符。Xargs 支持 0 字节,find 也支持。我会执行“find -print0”,然后执行“xargs -0”。 (3认同)
  • 对我来说,这是最好的答案-Oneliner提供开箱即用的工具 (2认同)
  • 这删除了我所有的文件。幸运的是我做了备份 (2认同)

ger*_*tra 8

并不是每个发行版都提供了一个rename支持正则表达式的实用工具,如上面的示例所示 - RedHat,Gentoo及其衍生产品等.

尝试使用的替代品是perl-renamemmv.


Cre*_*eak 8

编辑:找到一种更好的方法来列出文件而不使用IFSls仍然sh符合要求.

我会为此做一个shell脚本:

#!/bin/sh
for file in *.srt; do
  if [ -e "$file" ]; then
    newname=`echo "$file" | sed 's/^.*\([0-9]\+\)x\([0-9]\+\).*$/S0\1E\2.srt/'`
    mv "$file" "$newname"
  fi
done
Run Code Online (Sandbox Code Playgroud)

上一个脚本:

#!/bin/sh
IFS='
'
for file in `ls -1 *.srt`; do
  newname=`echo "$file" | sed 's/^.*\([0-9]\+\)x\([0-9]\+\).*$/S0\1E\2.srt/'`
  mv "$file" "$newname"
done
Run Code Online (Sandbox Code Playgroud)


igr*_*k51 8

使用正则表达式重命名

它的安装非常简单(与其他工具不同):

pip3 install regex-rename
Run Code Online (Sandbox Code Playgroud)

进行重命名:

regex-rename "(\d{1})x(\d{2})" "S0\1E\2.srt" --rename
Run Code Online (Sandbox Code Playgroud)

--rename首先尝试“空运行”模式(不带标志),在实际重命名之前检查它是否看起来不错。它会向您显示与每个组匹配的内容,以便您可以调试正则表达式,直到它正常为止。它需要 2 个参数:匹配器和替换模式,没有奇怪的s/.../.../语法。另外,我懒得做完整的匹配,它只适用于季节+剧集模式。

我自己做了它,因为我发现没有像这样的像样的工具。我很想听听您的反馈。


mei*_*muh 7

如果您的 Linux 不提供rename,您还可以使用以下命令:

find . -type f -name "Friends*" -execdir bash -c 'mv "$1" "${1/\w+\s*-\s*(\d)x(\d+).*$/S0\1E\2.srt}"' _ {} \;
Run Code Online (Sandbox Code Playgroud)

我经常使用此代码片段在控制台中使用正则表达式执行替换。

我不太擅长 shell 东西,但据我理解这段代码,它的解释是这样的:你的find的搜索结果将被传递到 bash 命令(bash -c),你的搜索结果将在其中位于$1内作为源文件。接下来的目标是子 shell 中替换的结果,其中$1的内容(此处:parameter-substituion { 1 //find/replace}中的1)也将是您的搜索结果。{}将其传递给-execdir的内容

更好的解释将不胜感激:)

请注意:我只复制粘贴了您的正则表达式;请先使用示例文件进行测试。根据您的系统,您可能需要将 \d 和 \w 更改为字符类,例如 [[:digit:]] 或 [[:alpha:]]。然而, \1 应该适用于组。


小智 6

我认为最简单也是通用的方法是使用for loop sedmv。首先,您可以在管道中检查正则表达式替换:

ls *.srt | sed -E 's/.* ([0-9])x([0-9]{2}) .*(\.srt)/S\1E\2\3/g'
Run Code Online (Sandbox Code Playgroud)

如果它打印出正确的替换,只需将其放入for loopwith中即可mv

for i in $(ls *.srt); do 
    mv $i $(echo $i | sed -E 's/.* ([0-9])x([0-9]{2}) .*(\.srt)/S\1E\2\3/g') 
    done
Run Code Online (Sandbox Code Playgroud)


xox*_*xox 5

使用mmv(质量移动?)

它简单但有用:它*用于?匹配字符串和#X替换字符串中的任何字符串和任何字符,以引用第X个匹配项。

在您的情况下:

mmv 'Friends - 6x?? - Tow *.srt' 'S06E#1#2.srt'
Run Code Online (Sandbox Code Playgroud)

这里#1#2代表被??(匹配#1和#2)捕获的两位数字。
因此,进行了以下替换:

Friends - 6x?? - Tow *           .srt    matches
Friends - 6x03 - Tow Ross' Denial.srt    which is replaced by
            ??
        S06E03.srt
Run Code Online (Sandbox Code Playgroud)

mmv还提供通过[]和匹配;

您不仅可以重命名,还可以移动,复制,追加链接文件。

阅读上面链接的手册页以获得更多信息!

就个人而言,我用它来填充数字,使得编号的文件出现在所需的顺序排序的字典序时:file_?.extfile_0#1.ext