根据模式在Linux中重命名大量文件

时间:2011-06-11 15:01:25

标签: linux sysadmin

我正在尝试用mv命令做三件事,但不确定它是否可能?可能需要一个脚本。不知道怎么写。所有文件都在同一个文件夹中。

1)以v9.zip结尾的文件应该是.zip(v9已删除)

2)包含_的文件应为 -

3)小写字母旁边的大写字母(或大写字母旁边的小写)旁边的文件应该有一个空格。因此,MoveOverNow将会移动到现在,并且ruNaway将会消失 [A-Z] [a-z]或[a-z] [A-Z]变为[A-Z] [a-z]和[a-z] [A-Z]

5 个答案:

答案 0 :(得分:20)

大多数基于Debian / Ubuntu的发行版都提供了rename命令,这是由Robin Barker根据Larry Wall 1998年左右的原始代码编写的(!)。

以下是文档的摘录:

  "rename" renames the filenames supplied according to the rule specified as the first argument.  The perlexpr argument is a Perl expression which is expected to modify the $_ string in Perl for at least some of the filenames
  specified.  If a given filename is not modified by the expression, it will not be renamed.  If no filenames are given on the command line, filenames will be read via standard input.

  For example, to rename all files matching "*.bak" to strip the extension, you might say

          rename 's/\.bak$//' *.bak

  To translate uppercase names to lower, you'd use

          rename 'y/A-Z/a-z/' *

它使用perl,因此您可以使用perl表达式来匹配模式,事实上我相信它的工作方式与tchrist的脚本非常相似。

批量文件重命名的另一组非常有用的工具是renameutils collection by Oskar Liljeblad。源代码由自由软件基金会托管。此外,许多发行版(尤其是基于Debian / Ubuntu的发行版)都有一个renameutils包与这些工具。

在其中一个发行版中,您可以使用以下命令安装:

$ sudo apt-get install renameutils

然后重命名文件只需运行以下命令:

$ qmv

它将弹出一个包含文件列表的文本编辑器,您可以使用编辑器的搜索和替换功能来操作它们。

答案 1 :(得分:9)

我没有对这些进行过测试,因此我将echo放在命令的前面,这样您就可以在删除回声之前尝试使用它们来实现它们。

1)

for f in *v9.zip; do echo mv "${f}" "${f%v9.zip}.zip"; done

2)

for f in *_*; do echo mv "${f}" "${f//_/-}"; done

关于你的第三个问题,我确信它也可以做到,但可能比原始shell单行更有效,正如@tchrist所提到的那样。

答案 2 :(得分:8)

我最喜欢的解决方案是my own rename script。映射到您的问题的最简单的例子是:

% rename 's/_/-/g' *
% rename 's/(\p{Lower})(\p{Upper})/$1 $2/g' *

虽然我真的讨厌我的文件名中的空格,特别是垂直空格:

 % rename 's/\s//g' *
 % rename 's/\v//g' *

等等。它基于The Larry Wall的剧本,但扩展了选项,如:

usage: /home/tchrist/scripts/rename [-ifqI0vnml] [-F file] perlexpr [files]
    -i          ask about clobbering existent files
    -f          force clobbers without inquiring
    -q          quietly skip clobbers without inquiring
    -I          ask about all changes
    -0          read null-terminated filenames
    -v          verbosely says what its doing 
    -V          verbosely says what its doing but with newlines between old and new filenames
    -n          don't really do it
    -m          to always rename
    -l          to always symlink
    -F path     read filelist to change from magic path(s)

如您所见,它不仅可以更改文件的名称,还可以更改符号链接指向使用相同模式的位置。您不必使用s///模式,尽管通常会使用{{1}}模式。

other tools in that directory主要用于Unicode工作,其中有一些超级有用的工作。

答案 3 :(得分:3)

以上答案适用于Debian,Ubuntu等

对于RHEL和co:重命名from_pattern to_pattern文件

答案 4 :(得分:2)

我认为链接已损坏,我在tchrist的帖子中找不到webarchive中的重命名脚本页面,所以这是Perl中的另一个。

#!/usr/bin/perl
# -w switch is off bc HERE docs cause erroneous messages to be displayed under
# Cygwin
#From the Perl Cookbook, Ch. 9.9
# rename - Larry's filename fixer
$help = <<EOF;
Usage: rename expr [files]

This script's first argument is Perl code that alters the filename 
(stored in \$_ ) to reflect how you want the file renamed. It can do 
this because it uses an eval to do the hard work. It also skips rename
calls when the filename is untouched. This lets you simply use 
wildcards like rename EXPR * instead of making long lists of filenames.

Here are five examples of calling the rename program from your shell:

% rename 's/\.orig$//'  *.orig
% rename 'tr/A-Z/a-z/ unless /^Make/'  *
% rename '$_ .= ".bad"'  *.f
% rename 'print "$_: "; s/foo/bar/ if <STDIN> =~ /^y/i'  *
% find /tmp -name '*~' -print | rename 's/^(.+)~$/.#$1/'

The first shell command removes a trailing ".orig" from each filename.

The second converts uppercase to lowercase. Because a translation is
used rather than the lc function, this conversion won't be locale-
aware. To fix that, you'd have to write:

% rename 'use locale; $_ = lc($_) unless /^Make/' *

The third appends ".bad" to each Fortran file ending in ".f", something
a lot of us have wanted to do for a long time.

The fourth prompts the user for the change. Each file's name is printed
to standard output and a response is read from standard input. If the
user types something starting with a "y" or "Y", any "foo" in the 
filename is changed to "bar".

The fifth uses find to locate files in /tmp that end with a tilde. It 
renames these so that instead of ending with a tilde, they start with
a dot and a pound sign. In effect, this switches between two common 
conventions for backup files
EOF

$op = shift or die $help;
chomp(@ARGV = <STDIN>) unless @ARGV;
for (@ARGV) {
    $was = $_;
    eval $op;
    die $@ if $@;
    rename($was,$_) unless $was eq $_;
}