如何在Perl中更改文件名的大小写?

时间:2009-03-24 15:50:26

标签: perl filenames

我正在尝试创建一个将我的所有文件名重命名为Camel / Capital Case的进程。我必须得到的最接近的是:

perl -i.bak -ple 's/\b([a-z])/\u$1/g;' *.txt # or similar .extension.

这似乎创建了一个备份文件(当我验证这是我想要的时候我会删除它);但它不是重命名文件,而是重命名文件内的文本。有更简单的方法吗?理论是我有几种不同格式的办公文件,因为我有点肛门保留,并希望它们看起来像这样:

New Document.odt
Roffle.ogg
Etc.Etc
Bob Cat.flac
Cat Dog.avi

perl是否可以实现,或者我是否需要更改为其他语言/组合?

另外,无论如何都要使这个递归,这样/ foo / foo / documents重命名了所有文件,/ foo / foo / documents / foo也是如此?

6 个答案:

答案 0 :(得分:9)

您需要使用 rename

这是签名:


rename OLDNAME,NEWNAME

要使其递归,请将其与 File::Find 一起使用


use strict;
use warnings;
use File::Basename;
use File::Find;

#default searches just in current directory
my @directories = (".");

find(\&wanted,  @directories);

sub wanted {
  #renaming goes here
}

以下代码段将针对找到的所有文件执行想要内的代码。您必须完成想要中的一些代码才能执行您想要执行的操作。

编辑:我尝试使用File :: Find完成此任务,我认为你不能轻易实现它。您可以按照以下步骤取得成功:

  • 如果参数是dir,请将其大写并获取所有文件

  • 对于每个文件,如果是dir,请以此文件作为参数返回开头

  • 如果文件是常规文件,请将其大写

Perl在编写此脚本时遇到了问题。我在ruby中写了这个脚本:


require "rubygems"
require "ruby-debug"

# camelcase files

class File
    class << self
        alias :old_rename :rename
    end

    def self.rename(arg1,arg2)
        puts "called with #{arg1} and #{arg2}"
        self.old_rename(arg1,arg2)
    end
end

def capitalize_dir_and_get_files(dir)
    if File.directory?(dir)
        path_c          = dir.split(/\//)
        #base           = path_c[0,path_c.size-1].join("/")
        path_c[-1].capitalize!  
        new_dir_name    = path_c.join("/")
        File.rename(dir,new_dir_name)
        files = Dir.entries(new_dir_name) - [".",".."]
        files.map! {|file| File.join(new_dir_name,file)}
        return files 
    end
    return []
end

def camelize(dir)
    files = capitalize_dir_and_get_files(dir)
    files.each do |file|
        if File.directory?(file)
            camelize(file.clone)
        else
            dir_name    = File.dirname(file)
            file_name   = File.basename(file)
            extname     = File.extname(file)
            file_components = file_name.split(/\s+/)
            file_components.map! {|file_component| file_component.capitalize}           
            new_file_name = File.join(dir_name,file_components.join(" "))
            #if extname != ""
            #   new_file_name += extname
            #end
            File.rename(file,new_file_name)
        end
    end
end

camelize(ARGV[0])

我在我的电脑上尝试了这个脚本,它按照你提到的规则将所有目录,子目录和文件大写。我认为这是你想要的行为。很抱歉没有提供perl版本。

答案 1 :(得分:5)

大多数系统都有重命名命令....

NAME        重命名 - 重命名多个文件

概要        重命名[-v] [-n] [-f] perlexpr [files]

说明        “rename”重命名根据指定为第一个参数的规则提供的文件名。 perlexpr参数是一个Perl表达式        应该至少修改一些指定文件名的Perl中的$ _字符串。如果表达式未修改给定的文件名,        它不会被重命名。如果命令行中没有给出文件名,则将通过标准输入读取文件名。

   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/' *

OPTIONS        -v, - verbose                详细:成功重命名文件的打印名称。

   -n, --no-act
           No Action: show what files would have been renamed.

   -f, --force
           Force: overwrite existing files.

AUTHOR        拉里沃尔

DIAGNOSTICS        如果您提供无效的Perl表达式,则会出现语法错误。

答案 2 :(得分:3)

由于Perl在多个平台上运行得很好,让我警告您FAT(和FAT32等)文件系统将忽略仅更改文件名大小写的重命名。在Windows和Linux下都是如此,对于支持FAT文件系统的其他平台可能也是如此。

因此,除了Geo's answer之外,请注意您可能必须实际更改文件名(例如,通过在末尾添加字符),然后使用正确的名称将其更改回所需的名称情况下。

如果您只重命名NTFS文件系统上的文件或仅重命名ext2 / 3/4文件系统(或其他UNIX / Linux文件系统),那么您可能不需要担心这一点。我不知道Mac OSX文件系统是如何工作的,但由于它基于BSD,我认为它只允许你通过更改名称的大小写来重命名文件。

答案 3 :(得分:1)

我只是使用find命令重现子目录和mv进行重命名,但仍然利用Perl来重命名。

find /foo/foo/documents -type f \
     -execdir bash -c 'mv "$0" \
                          "$(echo "$0" \
                              | perl -pe "s/\b([[:lower:]])/\u\$1/g; \
                                          s/\.(\w+)$/.\l\$1/;")"' \
              {} \;

神秘,但它有效。

答案 4 :(得分:1)

另一个:

find . -type f -exec perl -e'
  map {
        ( $p, $n, $s ) = m|(.*/)([^/]*)(\.[^.]*)$|;
        $n =~ s/(\w+)/ucfirst($1)/ge;
        rename $_, $p . $n . $s;
      } @ARGV
  ' {} +

答案 5 :(得分:0)

请记住,在记住文件系统(FAT / NTFS)的情况下,您需要先将文件重命名为其他内容,然后再更改为大小写。从“etc.etc”到“Etc.Etc”的直接重命名将失败或被忽略,因此您需要进行两次重命名:“etc.etc”到“etc.etc~”然后“etc.etc~”以“Etc.Etc”为例。

相关问题