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

时间:2012-08-04 15:13:29

标签: 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

我希望将它们重命名为以下

S06E03.srt
S06E20.srt
S06E05.srt

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

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

8 个答案:

答案 0 :(得分:54)

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

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

在OpenSUSE,RedHat,Gentoo上,您必须使用rename的Perl版本。 This answer显示了如何获得它。在Arch上,包名为perl-rename

答案 1 :(得分:8)

真的很酷lil diddy。找+ perl + xargs + mv

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

find . -type f | perl -pe 'print $_; s/input/output/' | xargs -n2 mv

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

OldName.ext    NewName.ext
OldName.ext    NewName.ext
OldName.ext    NewName.ext
OldName.ext    NewName.ext

我的系统上没有Perl rename

它是如何运作的?

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

答案 2 :(得分:7)

并非每个发行版都提供支持正则表达式的rename实用程序,如上例中所示 - RedHat,Gentoo及其衍生产品等。

尝试使用的替代方法是perl-renamemmv

答案 3 :(得分:7)

修改: 找到了一种更好的方式来列出文件而不使用IFSls,同时仍然是{{1}合规。

我会为此做一个shell脚本:

sh

上一个脚本:

#!/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

答案 4 :(得分:5)

使用mmv(质量移动?)

它很简单但有用:它对任何字符串使用*,对匹配字符串中的任何字符使用?,在替换字符串中使用#X来引用第X个匹配。

在你的情况下:

mmv 'Friends - 6x?? - Tow *.srt' 'S06E#1#2.srt'

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

Friends - 6x?? - Tow *           .srt    matches
Friends - 6x03 - Tow Ross' Denial.srt    which is replaced by
            ↓↓
        S06E03.srt

mmv还提供[]以及;的匹配。

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

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

就我个人而言,我使用它来填充数字,这样当按字典顺序排序时,编号文件按所需顺序显示:file_?.extfile_0#1.ext

答案 5 :(得分:1)

如果您的linux不提供重命名,您还可以使用以下内容:

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

我经常使用这个片段在我的控制台中使用正则表达式执行替换。

我的shell内容不是很好,但据我了解这段代码,其解释如下: find 的搜索结果将传递给bash-command ( bash -c )您的搜索结果将作为源文件位于 $ 1 内。后面的目标是子shell中替换的结果,其中 $ 1 的内容(此处: 1 在您的参数替换中 { 1 //查找/替换} )也将是您的搜索结果。 {} 将其传递给 -execdir

的内容

更好的解释将受到很多赞赏:)

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

答案 6 :(得分:1)

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

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

如果打印正确的替换,只需将其与for loop放在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

答案 7 :(得分:0)

您可以使用rnm

rnm -rs '/\w+\s*-\s*(\d)x(\d+).*$/S0\1E\2.srt/' *.srt

说明:

  1. -rs:替换/search_regex/replace_part/modifier
  2. 形式的字符串
  3. (\d)(\d+)中的(\d)x(\d+)分别是两个捕获的群体(\1\2)。
  4. 更多示例here

相关问题