Donnerstag, 22. November 2012

Ruby: Dateien mit Daten aus CSV umbenennen

Heute mal wieder ein Beispiel aus der Praxis wie wir mit Hilfe eines Ruby-Scripts Dateien gemäß den Angaben in einer CSV-Datei umbenennen können.

Die Ausgangslage sah folgendermaßen aus: Zum einen hatte ich einen Order (fotos2) mit Bildern, die nach dem folgenden Muster benannt waren:

001_außen.jpg
001_innen.jpg
002_logo.jpg

Zum anderen hatte ich eine CSV-Datei (namen.csv) mit folgendem Inhalt:

"id";"name"
"001";"Cafe Schaefer"
"002";"Brauhaus"

Die Anforderung war es jetzt, die Dateinamen in diese Form zu ändern:

001_Cafe Schaefer_1.jpg
001_Cafe Schaefer_2.jpg
002_Brauhaus_1.jpg

Die Lösung ist das unten gezeigte Script. Zunächst habe ich zwei Hashes angelegt und mit Hilfe von FasterCSV befüllt. Die Keys in beiden Hashes bilden die ID aus Spalte 1 (row[0]). merchant_names_hash speichert dabei die Namen nach dem Muster "002 => Brauhaus", merchant_foto_amount ist einfach ein Counter mit dem Startwert 1, also z.B. "001 => 1". Anschließend werden die Dateinamen aus dem Verzeichnis in einen Array geschrieben und durch iteriert. Dabei extrahiere ich zunächst die ID aus dem Dateinamen und schaue ob diese als Key im Hash merchant_names_hash enthalten ist. Wenn ja wird mit den Informationen aus diesem Hash und dem Wert aus dem Counter ein neuer Dateiname gebildet, der Counter einen hochgezählt und abschließend die Datei umbenannt.

require 'rubygems'
require 'fastercsv'

basedir = "./fotos2/"
csv_file = "namen.csv"

merchant_names_hash = Hash.new
merchant_foto_amount = Hash.new

FasterCSV.foreach(csv_file, :quote_char => '"', :col_sep =>';', :row_sep =>:auto) do |row|
  merchant_names_hash.store ("#{row[0]}","#{row[1]}")
  merchant_foto_amount.store ("#{row[0]}",1)
end

files = Dir.glob("#{basedir}*")

files.each do |file|
  name = "#{file}"
  filebasename = File.basename(file)
  
  if filebasename =~ /^(\w*)_/ then
    foto_id = $1
  end
  
  if merchant_names_hash.has_key?(foto_id) then
    newname = "#{basedir}/#{foto_id}_#{merchant_names_hash [foto_id]}_#{merchant_foto_amount [foto_id]}.jpg"
    merchant_foto_amount [foto_id] += 1
    File.rename(name, newname)
  end

end

Keine Kommentare:

Kommentar veröffentlichen