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

时间:2022-12-01 10:33:13

I have a set of files named like:

我有一组文件命名为:

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

and I want to rename them like the following

我想把它们重命名为如下所示

S06E03.srt
S06E20.srt
S06E05.srt

what should I do to make the job done in linux terminal? I have installed rename but U get errors using the following:

我应该怎么做才能在linux终端上完成这项工作?我已经安装了rename,但是你会收到以下错误信息:

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

7 个解决方案

#1


39  

You forgot a dot in front of the asterisk:

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

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

On OpenSUSE, RedHat, Gentoo you have to use Perl version of rename. This answer shows how to obtain it. On Arch, the package is called perl-rename.

在OpenSUSE、RedHat和Gentoo上,您必须使用Perl版本的rename。这个答案显示了如何获得它。在Arch上,这个包称为perl-rename。

#2


7  

Not every distro ships a rename utility that supports regexes as used in the examples above - RedHat, Gentoo and their derivatives amongst others.

不是每个发行版都提供了一个重命名实用程序,它支持上面示例中使用的regexes——RedHat、Gentoo以及它们的衍生工具。

Alternatives to try to use are perl-rename and mmv.

替代尝试使用的是perl-rename和mmv。

#3


5  

Edit: found a better way to list the files without using IFS and ls while still being sh compliant.

编辑:找到一种更好的方法,在不使用IFS和ls的情况下列出文件,同时仍然遵循sh。

I would do a shell script for that:

我将为此编写一个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

Previous script:

之前的脚本:

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

#4


3  

Use mmv (mass-move?)

It's simple but useful: It uses * for any string and ? for any character in the match string and #X in the replace string to refer to the X-th match.

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

In your case:

在你的例子:

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

Here #1#2 represent the two digits which are captured by ?? (match #1 and #2).
So the following replacement is made:

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

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

mmv also offers matching by [ and ] and ;.

mmv还提供[and]和;

You can not only rename, but also move, copy, append and link files.

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

Read the man page linked above for more!

阅读上面链接的手册页了解更多信息!

#5


1  

Really cool lil diddy.

很酷的李尔老爹。

xargs -n2 makes it possible to print two arguments per line. When combined with Perl's print $_ (to print the $STDIN first), it makes for a powerful renaming tool.

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

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

Results of perl -pe 'print $_; s/OldName/NewName/' | xargs -n2 end up being:

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

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

I did not have Perl's rename readily available on my system.

我的系统上没有Perl的重命名。

#6


0  

You can use rnm:

您可以使用rnm:

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

Explanation:

解释:

  1. -rs : replace string of the form /search_regex/replace_part/modifier
  2. -rs:替换窗体/search_regex/replace_part/修饰符的字符串
  3. (\d) and (\d+) in (\d)x(\d+) are two captured groupes (\1 and \2 respectively).
  4. (\d)和(\d+)在(\d)x(\d+)中分别是两个捕获的组(\1和\2)。

More examples here.

更多的例子。

#7


0  

if your linux does not offer rename, you could also use the following:

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

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

i use this snippet quite often to perform substitutions with regex in my console.

我经常在我的控制台中使用这个片段来执行regex的替换。

i am not very good in shell-stuff, but as far as i understand this code, its explanation would be like: the search results of your find will be passed on to a bash-command (bash -c) where your search result will be inside of $1 as source file. the target that follows is the result of a substitution within a subshell, where the content of $1 (here: just 1 inside your parameter-substituion {1//find/replace}) will also be your search result. the {} passes it on to the content of -execdir

我在shell方面不是很好,但就我理解这段代码而言,它的解释是:你的搜索结果将被传递到一个bash命令(bash -c),你的搜索结果将在$1作为源文件的内部。下面的目标是在子shell中进行替换的结果,其中$1的内容(这里:在您的参数-取代基{1//查找/替换}中只有1)也将是您的搜索结果。{}将其传递到-execdir的内容

better explanations would be appreciated a lot :)

如果有更好的解释,我将不胜感激。

please note: i only copy-pasted your regex; please test it first with example files. depending on your system you might need to change \d and \w to character classes like [[:digit:]] or [[:alpha:]]. however, \1 should work for the groups.

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

#1


39  

You forgot a dot in front of the asterisk:

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

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

On OpenSUSE, RedHat, Gentoo you have to use Perl version of rename. This answer shows how to obtain it. On Arch, the package is called perl-rename.

在OpenSUSE、RedHat和Gentoo上,您必须使用Perl版本的rename。这个答案显示了如何获得它。在Arch上,这个包称为perl-rename。

#2


7  

Not every distro ships a rename utility that supports regexes as used in the examples above - RedHat, Gentoo and their derivatives amongst others.

不是每个发行版都提供了一个重命名实用程序,它支持上面示例中使用的regexes——RedHat、Gentoo以及它们的衍生工具。

Alternatives to try to use are perl-rename and mmv.

替代尝试使用的是perl-rename和mmv。

#3


5  

Edit: found a better way to list the files without using IFS and ls while still being sh compliant.

编辑:找到一种更好的方法,在不使用IFS和ls的情况下列出文件,同时仍然遵循sh。

I would do a shell script for that:

我将为此编写一个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

Previous script:

之前的脚本:

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

#4


3  

Use mmv (mass-move?)

It's simple but useful: It uses * for any string and ? for any character in the match string and #X in the replace string to refer to the X-th match.

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

In your case:

在你的例子:

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

Here #1#2 represent the two digits which are captured by ?? (match #1 and #2).
So the following replacement is made:

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

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

mmv also offers matching by [ and ] and ;.

mmv还提供[and]和;

You can not only rename, but also move, copy, append and link files.

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

Read the man page linked above for more!

阅读上面链接的手册页了解更多信息!

#5


1  

Really cool lil diddy.

很酷的李尔老爹。

xargs -n2 makes it possible to print two arguments per line. When combined with Perl's print $_ (to print the $STDIN first), it makes for a powerful renaming tool.

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

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

Results of perl -pe 'print $_; s/OldName/NewName/' | xargs -n2 end up being:

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

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

I did not have Perl's rename readily available on my system.

我的系统上没有Perl的重命名。

#6


0  

You can use rnm:

您可以使用rnm:

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

Explanation:

解释:

  1. -rs : replace string of the form /search_regex/replace_part/modifier
  2. -rs:替换窗体/search_regex/replace_part/修饰符的字符串
  3. (\d) and (\d+) in (\d)x(\d+) are two captured groupes (\1 and \2 respectively).
  4. (\d)和(\d+)在(\d)x(\d+)中分别是两个捕获的组(\1和\2)。

More examples here.

更多的例子。

#7


0  

if your linux does not offer rename, you could also use the following:

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

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

i use this snippet quite often to perform substitutions with regex in my console.

我经常在我的控制台中使用这个片段来执行regex的替换。

i am not very good in shell-stuff, but as far as i understand this code, its explanation would be like: the search results of your find will be passed on to a bash-command (bash -c) where your search result will be inside of $1 as source file. the target that follows is the result of a substitution within a subshell, where the content of $1 (here: just 1 inside your parameter-substituion {1//find/replace}) will also be your search result. the {} passes it on to the content of -execdir

我在shell方面不是很好,但就我理解这段代码而言,它的解释是:你的搜索结果将被传递到一个bash命令(bash -c),你的搜索结果将在$1作为源文件的内部。下面的目标是在子shell中进行替换的结果,其中$1的内容(这里:在您的参数-取代基{1//查找/替换}中只有1)也将是您的搜索结果。{}将其传递到-execdir的内容

better explanations would be appreciated a lot :)

如果有更好的解释,我将不胜感激。

please note: i only copy-pasted your regex; please test it first with example files. depending on your system you might need to change \d and \w to character classes like [[:digit:]] or [[:alpha:]]. however, \1 should work for the groups.

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