0

いくつかの異なるルールで膨大な数のファイルの名前を変更するスクリプトを書きたいと思います。いくつかから特定の文字列を削除し、正規表現で他の文字列の名前を変更し (そのうちのいくつかは、以前に文字列を削除したものになります)、ファイル名の番号に基づいて他の名前を変更する必要があります。

一般に、複数のディレクトリ (数百) があり、それらはすべて一般的に次のようになっているとします。

1234-pic_STUFF&TOREMOVE_2000.tiff
1234-pic_STUFF&TOREMOVE_4000.tiff
1234-MORESTUFFTOREMOVE-012.jpg
1234-MORESTUFFTOREMOVE-037.jpg
1234-STUFF&TOREMOVE.pptx.pdf        (don't ask about this one)
1234-ET.jpg
1234-DF.jpg

次のようなものに:

1234_smallNum.tiff
1234_bigNum.tiff
1234_smallNum.jpg
1234_bigNum.jpg
1234_CaseReport.pdf
1234_ET.jpg
1234_DF.jpg

perlスクリプトを使用して正規表現で名前を変更するシェルスクリプトをすでに持っています(SOから外しましたが、参照するために再び見つけることができません)。それらは と に似remove_stuff_to_remove.shておりrename_case_reports.sh、各ディレクトリに cd して、入力なしで呼び出すことで個別に実行できます。

ただし、数値に基づいてファイル名を変換する方法がわかりません (2000 と 012 を smallNum に、4000 と 037 を bigNum に変換します。これらの数値は大きく異なることに注意してください。範囲や正規表現を使用することはできません。数値を比較してください。)

また、プロセス全体を自動化する方法がわからないため、これらすべてのディレクトリのルート ディレクトリから 1 つのスクリプトを呼び出すと、これらすべてのことを実行してくれます。find私は正規表現をかなりよく理解していますが、コマンドやシェルスクリプト全般についてはあまりうまくいっていません。

また、私は Bash と言いますが、実際には、これが Java、C、Python、Ruby、または Lisp でより適切に実行できるとしたら、それらの言語をはるかによく知っているので、これらのファイルが私にダンプされる前に、これに対する解決策が欲しいだけです。 (翌月かそこらで)...

4

2 に答える 2

1

本当に-bashで自分を苦しめないでください。お気に入りのスクリプト言語を使用してください。以下は、Ruby でこれにアプローチする方法を示しています。急いで書いたので、笑わないでください:

#!/usr/bin/env ruby

require 'find'

def move(path, old_name, new_suffix)
    number = old_name.sub(/^(\d+).*/,'\1')
    File.rename(path+'/'+old_name, path+'/'+number+'_'+new_suffix)
end

where_to_look = ARGV[0] || '.'
Find.find(where_to_look) do |dir|
    path = where_to_look+'/'+dir
    next if !File.directory?(path)
    entries = Dir.entries(path).select{|x| File.file?(path+'/'+x) }
    next if entries.size != 7

    %w(tiff jpg).each do |ext|
        imgs = entries.select{|x| x =~ /\d+\.#{ext}$/ }
        next if imgs.size != 2
        imgs.sort{|a,b| ai = $1.to_i if a =~ /(\d+)\.#{ext}$/ ; bi = $1.to_i if b =~ /(\d+)\.#{ext}$/ ; ai <=> bi }
        move(path, imgs.first, 'smallNum.'+ext)
        move(path, imgs.last, 'bigNum.'+ext)
    end
    report = entries.detect{|x| x =~ /\.pptx\.pdf$/ }
    move(path, report, 'CaseReport.pdf') if !report.nil?
    %w(ET DF).each do |code|
        file = entries.detect{|x| x =~ /^\d+-#{code}\.jpg$/ }
        move(path, file, code+'.jpg') if !file.nil?
    end
end
于 2013-11-14T20:59:03.707 に答える
1

Bash の文字列置換:

$ match="foo"
$ repl="bar"
$ value="___foo___"
$ echo "${value/$match/$repl}"
___bar___

http://tldp.org/LDP/abs/html/string-manipulation.html

このパターンを各変換に適用できます。

$ for file in $(find . -name "*-pic_STUFF\&TOREMOVE_2000.tiff"); do
    mv "$file" "${file/-pic_STUFF\&TOREMOVE_2000.tiff/_smallNum.tiff}"; done
于 2013-11-15T11:11:49.887 に答える