2013-11-14 6 views
0

Я хотел бы написать скрипт, чтобы переименовать огромное количество файлов по нескольким различным правилам. Мне нужно удалить определенную строку из некоторых, а затем переименовать другие по регулярному выражению (некоторые из которых будут теми, из которых я ранее удалил строку), а затем переименовать другие на основе чисел в именах файлов.Bash - Переименование файлов

В общем, скажем, у меня есть несколько каталогов (сотни), которые все выглядят обычно так:

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, и я могу записывать их в каждый каталог и выполнять их индивидуально, вызывая их без ввода.

Однако, я не знаю, как преобразовать имена файлов на основе чисел (2000 и 012 на smallNum; 4000 и 037 на bigNum, обратите внимание, что эти цифры сильно различаются, поэтому я не могу пройти по диапазону или регулярному выражению , Я должен сравнивать числа друг с другом.)

И я не знаю, как автоматизировать весь процесс, чтобы я мог вызвать один скрипт из корневого каталога всех этих каталогов, и он сделает все эти вещи для меня. Я хорошо понимаю регулярные выражения, но я не очень хорошо справляюсь с командой find или с оболочкой в ​​целом.

Кроме того, я говорю Bash, но на самом деле, если это может быть лучше сделано в Java, C, Python, Ruby или Lisp, я знаю эти языки намного лучше, и я просто хочу, чтобы это решение до того, как я получу эти файлы, сбрасываемые на меня (в следующем месяце или около того) ...

+0

Как замечательный комментарий, Perl или Bash, по-видимому, являются наиболее подходящими вариантами для выполнения такого рода задач. –

+0

Я начинаю понимать. Вы уверены, что у вас не может быть более двух файлов в каталоге с тем же именем, с тем же расширением, но с другим номером? –

+0

Да, я уверен. Это медицинские данные, и для каждого из них не более 2 «сканирований» (но может быть только один, и в этом случае он считается небольшим). –

ответ

1

Действительно - не пытай себя бахом, просто используйте свой любимый язык сценариев. Ниже вы узнаете, как подойти к этому в 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 
+0

Вау просто показывает, как я устал в последнее время ...Я полностью забыл обо всех хороших файловых методах в Ruby ... Я застрял в идее использования bash и столкнулся с стеной. Я обвиняю своих профессоров, которые не позволят мне ничего использовать, кроме С этого семестра. : P –

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 
+0

Благодарим вас за пример замены строки Bash; Я никогда не видел, чтобы кто-то делал это раньше (+1 для этого). Но это не устраняет проблему сравнения двух чисел (2000 и 4000 - это просто примеры, так же легко может быть 3750 и 4100). –

Смежные вопросы