2016-09-20 2 views
2

Ich habe ein Verzeichnis mit einer Anzahl von Dateien und Unterverzeichnissen. Ich muss diese Dateien in jedes Unterverzeichnis verschieben, abhängig von ihrer Benennung. Zum Beispiel:Verzeichnis mit einer Anzahl von Dateien und Unterverzeichnissen: Ich muss diese Dateien in jedes Unterverzeichnis verschieben, wie in Ruby

Dateien:

Hello.doc 
Hello.txt 
Hello.xls 
This_is_a_test.doc 
This_is_a_test.txt 
This_is_a_test.xls 
Another_file_to_move.ppt 
Another_file_to_move.indd 

Subdirectories:

Folder 01 - Hello 
Folder 02 - This_is_a_test 
Folder 03 - Another_file_to_move 

Was ich brauche, ist die drei Dateien mit dem Namen Hello in Ordner verschieben Folder 01 - Hello; Die drei Dateien namens This_is_a_test in Verzeichnis Folder 02 - This_is_a_test und die beiden Dateien Another_file_to_move in Verzeichnis namens Folder 03 - Another_file_to_move. Ich habe Hunderte von Dateien, nicht nur diese.

Wie es zu sehen ist, enthält der Ordnername den Namen der Datei am Ende, sondern am Anfang gibt es ein Folder + \s + a number + \s + a -. Dies ist ein globales Muster.

Irgendwelche Hilfe?

+1

Sie haben vergessen, uns zu sagen, was du bisher versucht hast. –

+0

Sicher. Ich habe viele Male 'FileUtils' zum Kopieren von Dateien, Verschieben, Umbenennen usw. verwendet. Was ich wirklich bekommen kann ist, wie man Ruby auf Dateinamen aufmerksam macht, ich dachte über eine Regex nach, aber mir fehlt der Vergleich zwischen Dateien und Ordnernamen. –

Antwort

3

Hetzen Sie nicht, versuchen Sie, Ihr Problem Schritt für Schritt zu lösen. Ich würde Ihr Problem in den folgenden Schritten lösen:

1. Separate Dateien aus Unterverzeichnisse

subdirectories, files = Dir['/path/to/the/directory/*'].partition{|path| File.directory?(path)} 
# TODO ... 

2. Iterate über die Dateien und den Basisnamen jeder Datei abrufen, ohne Verlängerung

subdirectories, files = Dir['/path/to/the/directory/*'].partition{|path| File.directory?(path)} 

files.each do |file| 
    basename = File.basename(file, '.*') 
    # TODO ... 
end 

3. Suchen Sie das Unterverzeichnis, in das die Datei gehen soll

subdirectories, files = Dir['/path/to/the/directory/*'].partition{|path| File.directory?(path)} 

files.each do |file| 
    basename = File.basename(file, '.*') 
    subdirectory = subdirectories.find {|d| File.basename(d) =~ /^Folder \d+ - #{Regexp.escape(basename)}$/} 
    # TODO ... 
end 

4. Verschieben Sie die Datei in das Verzeichnis

require 'fileutils' 

subdirectories, files = Dir['/path/to/the/directory/*'].partition{|path| File.directory?(path)} 

files.each do |file| 
    basename = File.basename(file, '.*') 
    subdirectory = subdirectories.find {|d| File.basename(d) =~ /^Folder \d+ - #{Regexp.escape(basename)}$/} 
    FileUtils.mv(file, subdirectory + '/') 
end 

Erledigt. Aber das Finden von Unterverzeichnissen mit regexp ist teuer und wir wollen das nicht für jede Datei machen. Kannst du es optimieren?

TIPP 1: Geschäftsspeicher für Zeit.
TIPP 2: Hash.

+0

Ausgezeichnet. Danke für die Erklärung. Ich werde versuchen, es zu optimieren :) –

0

Und hier ist ein schneller, aber nicht Cross-Plattform-Lösung (vorausgesetzt, Ihr Arbeitsverzeichnis ist das Verzeichnis, um die Dateien und Verzeichnisse enthalten), und der Code ist ein wenig chaotisch:

subdirectories = `ls -d ./*/`.lines.each(&:chomp!) 

subdirectories.each do |dir| 
    basename = dir =~ /\bFolder \d+ - (\w+)\/$/ && $1 
    next unless basename 
    `mv ./#{basename}.* #{dir}` 
end 
Verwandte Themen