2009-03-24 25 views
2

すべてのファイル名の名前をCamel/Capital Caseに変更するプロセスを作成しようとしています。そこに得るために私が持っている最も近いがこれです:Perlでファイル名の大文字/小文字を変更するにはどうすればよいですか?

(私は私が欲しいもの、これはありません確認しています時に削除されます)バックアップファイルを作成するようだ
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と同じようにすべてのファイルの名前が変更されるように、再帰的に行うことはありますか?

+0

現在のフォームが何であるかを指定していません。 – Axeman

答えて

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 
} 

次のスニペットは、すべてに対してを望んでいた内のコードを実行しますと一緒にそれを使用します見つかったファイル。あなたがしたいことを行うには、がほしいと思っているのコードの一部を完成させなければなりません。

EDIT:File :: Findを使用してこのタスクを達成しようとしましたが、簡単には達成できないと思います。あなたは、以下の手順を実行して成功することができます。

  • パラメータが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]) 

私は自分のPC上でスクリプトを試してみましたが、それはあなたが言及したルールによって、すべてのdirs、サブディレクトリとファイルを大文字にします。私はこれがあなたが望む行動だと思う。 perl版を提供していないのは残念です。

+0

http://search.cpan.org/dist/File-Find-Rule/lib/File/Find/Rule.pmはFile :: Findよりもきれいですが、YMMVです。 – ephemient

+0

私はFile :: Find :)を使ってかなり成長しました。私はそれがもっと好きです。 – Geo

+0

グローバルシンボル "@directories"には、bob.pl 5行目の明示的なパッケージ名が必要です。 コンパイルエラーのためにbob.plが中止されました。 bob.plを実行しようとしました(最新の編集で)^が結果です。 –

3

Perlは複数のプラットフォーム上でうまく動作するので、FAT(およびFAT32など)ファイルシステムはファイル名の大文字と小文字を変更するだけの名前変更を無視します。これはWindowsとLinuxでは当てはまり、おそらくFATファイルシステムをサポートする他のプラットフォームでも当てはまります。

Geo's answerに加えて、実際にファイル名を変更して(たとえば、末尾に文字を追加して)正しい大文字と小文字の名前に変更する必要があるかもしれないことに注意してください。

NTFSファイルシステムまたはext2/3/4ファイルシステム(または他のUNIX/Linuxファイルシステム)でのみファイルの名前を変更する場合は、おそらくこれを心配する必要はありません。 Mac OSXファイルシステムの仕組みはわかりませんが、BSDに基づいているので、名前の大文字/小文字を変更するだけでファイルの名前を変更できると思います。

+0

BSDファイルシステムとは異なり、OS XのデフォルトのHFS +は大文字と小文字を区別しません。私は、大文字と小文字のみの名前変更が動作するかどうかをテストするために、近くにMacを持っていません... – ephemient

+0

Mac(10.5)のデフォルトのHFS +ボリュームで大文字と小文字のみの名前を変更できない: "$ touch x && mv x X mv:' x 'と 'X'は同じファイル" –

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/;")"' \ 
       {} \; 

暗号が効いていますが、

+0

StackOverflowは許可しない10文字未満のコメント。私が言いたいのは、+ 1、オタクです。 – Geo

+0

私はそれを書いて恥ずかしいです。 – ashawley

5

ほとんどのシステムでは、renameコマンド....

NAME 名前の変更がある - 名前を変更し、複数のファイル

書式を 名前を変更[-v] [-n] [-f] perlexpr [ファイル]

説明 「名前を変更する」は、最初の引数として指定されたルールに従って指定されたファイル名の名前を変更します。 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 Larry Wall氏

診断 を使用すると、無効なPerlの式を与える場合は、構文エラーが発生します。もう1

1

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

場合-思い出しファイルシステム(FAT/NTFS)に、あなたはケースの変化に、その後、最初に何か他のものにファイルの名前を変更する必要があります覚えておいてください。 "etcetc"から "Etc.Etc"への直接的な名前変更は失敗するか無視されるので、 "etcetc"を "etcetc"に、次に "etcetc〜"という2つの名前を変更する必要があります。例えば「Etc.Etc」に変更する。

関連する問題