Вопрос

I'm struggling with a script to target specific XML files in a directory and rename them as copies with a different name.

I put in the puts statements for debugging, and, from what I can tell, everything looks OK until the FileUtils.cp line. I tried this with simpler text and it worked, but my overly complicated cp(file, file.gsub()) seems to be causing problems that I can't figure out.

def piano_treatment(cats)
  FileUtils.chdir('12Piano')
  src = Dir.glob('*.xml')

  src.each do |file|
    puts file
    cats.each do |text|
      puts text
      if file =~ /#{text}--\d\d/
        puts "Match Found!!"
        puts FileUtils.pwd
        FileUtils.cp(file, file.gsub!(/#{text}--\d\d/, "#{text}--\d\dBass "))
      end
    end
  end

end
piano_treatment(cats)

I get the following output in Terminal:

12Piano--05Free Stuff--11Test.xml
05Free Stuff
Match Found!!
/Users/mbp/Desktop/Sibelius_Export/12Piano
cp 12Piano--05Free Stuff--ddBass Test.xml 12Piano--05Free Stuff--ddBass Test.xml
/Users/mbp/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/fileutils.rb:1551:in `stat': No such file         or directory - 12Piano--05Free Stuff--ddBass Test.xml (Errno::ENOENT)

Why is \d\d showing up as "dd" when it should actually be numbers? Is this a single vs. double quote issue? Both yield errors.

Any suggestions are appreciated. Thanks.

EDIT One additional change was needed to this code. The FileUtils.chdir('12Piano') would change the directory for the first iteration of the loop, but it would revert to the source directory after that. Instead I did this:

def piano_treatment(cats)
  src = Dir.glob('12Piano/*.xml')

which sets the match path for the whole method.

Это было полезно?

Решение

Your replacement string is not a regex, so \d has no special meaning, but is just a literal string. You need to specify a group in your regex, and then you can use the captured group in your replacement string:

FileUtils.cp(file, file.gsub(/#{text}--(\d\d)/, "#{text}--\\1Bass "))

The parenthesis in the regex form the group, which can be used (by number) in the replacement string: \1 for the first group, \2 for the second, etc. \0 refers to the entire regex match.

Update

Replaced gsub!() with gsub() and escaped the backslash in the replacement string (to treat \1 as the capture group, not a literal character... Doh!).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top