2012-05-25 24 views
6

Kendim için bir programlama alıştırması olarak ruby ​​temelli bir dosya yeniden adlandırma programı çalıştırmaya çalışıyorum (linux altında yeniden adlandırıldığının farkındayım, ancak Ruby'yi öğrenmek istiyorum ve yeniden adlandırmak Mac'te mevcut değildir).ruby ​​dosyalarının nasıl yeniden adlandırılır?

Aşağıdaki koddan, dosya adının bu tür arama modelini görmesine rağmen, .include? yönteminin her zaman false döndürmesidir. include? işaretini açıklarsam, gsub()'un yeni bir dosya adı oluşturduğu görünmez (yani dosya adı aynı kalır). Birisi lütfen yanlış yaptığımı görmek için bir göz atabilir mi? Şimdiden bir demet teşekkürler!

İşte beklenen davranıştır: Geçerli klasördeki üç dosya olduğunu varsayarsak: Yakut komut, b1.jpg için b2 yeniden adlandırmak gerekir a1.jpg, a2.jpg ve a3.jpg . jpg, b3.jpg

#!/Users/Antony/.rvm/rubies/ruby-1.9.3-p194/bin/ruby 

puts "Enter the file search query" 
searchPattern = gets 
puts "Enter the target to replace" 
target = gets 
puts "Enter the new target name" 
newTarget = gets 
Dir.glob("./*").sort.each do |entry| 
    origin = File.basename(entry, File.extname(entry)) 
    if origin.include?(searchPattern) 
    newEntry = origin.gsub(target, newTarget) 
    File.rename(origin, newEntry) 
    puts "Rename from " + origin + " to " + newEntry 
    end 
end 
+0

üç 'gets' istemleri için ne girdi sağlıyoruz ... Auto1, car2 dönüştürülen/vardı? – bta

+0

Cidden 'rename' komutunun bunu daha iyi yapabileceğini düşünüyorum ... – texasbruce

+0

@texasbruce, Mac'te yeniden adlandır komutu yok. Belki macports bir şey var, ama sadece bir sürü perl betiği bulundu. Ama daha önce önerdiğim gibi, bu benim için – Antony

cevap

9

hafifçe değiştirilmiş versiyonu:

puts "Enter the file search query" 
searchPattern = gets.strip 
puts "Enter the target to replace" 
target = gets.strip 
puts "Enter the new target name" 
newTarget = gets.strip 
Dir.glob(searchPattern).sort.each do |entry| 
    if File.basename(entry, File.extname(entry)).include?(target) 
    newEntry = entry.gsub(target, newTarget) 
    File.rename(entry, newEntry) 
    puts "Rename from " + entry + " to " + newEntry 
    end 
end 

önemli farklar:

  • gets'dan aldığınız son satırın kaldırılması için .strip kullanın. Aksi takdirde, bu yeni satır karakteri tüm maç denemelerinizi bozar.
  • glob Çağrısında kullanıcı tarafından sağlanan arama modelini, her şey için deşiştirmek yerine kullanın ve daha sonra manuel olarak filtreleyin.
  • gsub ve rename çağrıları origin yerine entry (tam dosya adıdır) çağrılarında kullanın. origin gerçekten sadece .include? testi için kullanışlıdır. Dosya isminin bir parçası olduğu için, rename ile kullanılamaz. Kötüye kullanmamaya engel olmak için origin değişkenini tamamen kaldırdım. Beklediğiniz gibi üç giriş istemleri için *.jpg, a ve b giren senin örneğin klasör yapısı için

, (sırasıyla) dosyalarını yeniden adlandırmak gerekir.

+0

Ahh! Açıklama için teşekkürler. En azından belgelerden (ruby-doc.org), bu şerit (önde gelen ve sondaki beyaz boşlukları kaldırır) ve chomp (yeni satırları kaldırır) gösterdiğim görülüyor, bu yüzden gets.chomp.strip ile sona erdi Umarım bu overkill değildir . Her neyse, senaryo mükemmel çalışıyor! – Antony

+0

@ Antony- Newlines, Ruby'nin "beyaz boşluk" olarak gördüğü şeylerin bir parçasıdır, bu yüzden hem "chomp" hem de "strip" yapmak gereksizdir. 'strip',' chomp''nın yaptığı her şeyi yapar. – bta

2

Senin sorunun gets dizesinin sonunda bir yeni satır döndürür olmasıdır. Yani, "foo" yazarsanız, searchPattern, "foo\n" olur. En basit bir düzeltmedir:

searchPattern = gets.chomp 

Biraz kodunuzu yeniden olabilir:

$stdout.sync 
print "Enter the file search query: "; search = gets.chomp 
print "Enter the target to replace: "; target = gets.chomp 
print " Enter the new target name: "; replace = gets.chomp 
Dir['*'].each do |file| 
    # Skip directories 
    next unless File.file?(file) 
    old_name = File.basename(file,'.*') 
    if old_name.include?(search) 
    # Are you sure you want gsub here, and not sub? 
    # Don't use `old_name` here, it doesn't have the extension 
    new_name = File.basename(file).gsub(target,replace) 
    File.rename(file, new_path) 
    puts "Renamed #{file} to #{new_name}" if $DEBUG 
    end 
end 
+0

Chomp'u işaretlediğiniz için teşekkür ederiz. Her gün yeni bir şey öğrenmek. – Antony

+0

Dosya.rename içine göndermekte olduğunuz "new_path" argümanı nerede ayarlanıyor? Belki bunun yerine File.rename (dosya, yeni_adı) kastediyorsunuz? Aksi takdirde bunu +1 – emery

3

Kopyalanan dosyaların adlarını düzeltmek için kabul edilen yanıtı kullandım.

Dir.glob('./*').sort.each do |entry| 
    if File.basename(entry).include?(' copy') 
    newEntry = entry.gsub(' copy', '') 
    File.rename(entry, newEntry) 
    end 
end 
0

İşte (desen eşleştirme olmadan) Bugün kullandım kısa versiyon

kaydet bu kadar rename.rb dosyasıdır ve yakut adlandırmak ile komut istemine içine çalıştırın.rb

count = 1 
newname = "car" 
Dir["/path/to/folder/*"].each do |old| 
    File.rename(old, newname + count.to_s) 
    count += 1 
end 

Ben _MG_2435.JPG kopyası

İlgili konular