File.rename not working on Windows - ruby

Here's the code:
files = Dir.glob("*")
files.each do |file|
if File.extname(file) == ".pdf"
format = file.split(".pdf")
format = format.join("").split(" ")
format[0] = format[0].gsub(".","/")
format[0] << "_"
format[0].prepend("_")
format[-1] << ".pdf"
format = format.join("")
puts "Changed #{file} to #{format}"
File.rename(file,format)
end
end
It is running from the same directory as the files. I have tried giving the File.rename parameters absolute paths as well, by appending the result of Dir.pwd to them. Code isn't very clean as it was something I whipped up real quick, please excuse that.
I get the following error:
Changed 05.01.14 Mid-Day 1.pdf to _05/01/14_Mid-Day1.pdf
script.rb:12:in `rename': No such file or directory - (05.01.14 Mid-Day 1.pdf, _05/01/14_Mid-Day1.pdf) (Errno::ENOENT)
from script.rb:12:in `block in <main>'
from script.rb:2:in `each'
from script.rb:2:in `<main>'
If I call File.exists?(file) it comes back as true. I'm thoroughly confused on why this doesn't work.
I am on running this on Windows.

The directory structure _05/01 does not seem to exist. You need to create the directories first with FileUtils.mkdir_p before being able to move the file there.

Related

Getting error while opening file , i have created folder with book_name > chapter_name in code and then creating file

In child folder(chapter_number), i am creating file
#!/usr/bin/env ruby
require 'roo'
Dir.glob("**/*.xlsx") do |file|
xlsx = Roo::Spreadsheet.open(file)
bookname = xlsx.column(1)
cahpter_number_array = xlsx.column(2).uniq
cahpter_number_array.each do |chapter|
book_name = bookname[1] if bookname
chapter_number = chapter if (cahpter_number_array && (chapter != "Chapter"))
Dir.mkdir(book_name) unless File.exists?(book_name)
Dir.mkdir("#{book_name}/#{chapter_number}") unless File.exists?("#{book_name}/#{chapter_number}")
xlsx.column(3).each do |md|
output_name = "#{book_name}/#{chapter_number}/#{File.basename(md.partition('-').first, '.*')}.md" if (md != "Verse")
output = File.open("#{output_name}", 'w')
output << "hello"
end
end
end
Error:
`initialize': Is a directory # rb_sysopen - . (Errno::EISDIR)
Below link is my source file:
source file link
Come on now, that isn't really your code. You can't call partition on a number:
file_name = [1,2,3,4,5,6,7]
file_name.each do |md|
... md.partition('-')
so you would have gotten an error for that before getting the error you posted.
In any case, the error message is saying that outputname is set equal to "." and when ruby tries to execute File.open(".", 'w') ruby finds that "." is the name of a directory on your system, and you can't write a directory. You can witness the same error doing this:
~/ruby_programs$ mkdir my_dir
~/ruby_programs$ irb
2.3.0 :001 > File.open('my_dir', 'w')
Errno::EISDIR: Is a directory # rb_sysopen - my_dir
from (irb):1:in `initialize'
from (irb):1:in `open'
from (irb):1
from /Users/7stud/.rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'

Ruby Filename error?

I forked this gist from https://gist.github.com/mattdipasquale/571405
I am getting the following error:
deDUPER.rb:14:in `read': Invalid argument - /Volumes/Drobo #1 2009-2012/AMNH Video/2012/2012-01-17 Creatures of Light/Capture Scratch/Art 3:9/Capture Scratch/2012-03-09_microraptor livestream/A Cam_Microraptor livestream.mov (Errno::EINVAL)
from deDUPER.rb:14:in `block in <main>'
from deDUPER.rb:10:in `each'
from deDUPER.rb:10:in `<main>'
I think it is caused from illegal characters in the file or folder names, but i'm not sure. I don't want to change the file or folder names because they are linked to old Final Cut Pro project files that rely on referenced filepaths to keep the project intact. Does anyone have experience with this? Is there a way I can get this script to work without having to change the file or folder names?
# Define the unique method that removes duplicates
#!/usr/bin/ruby
require 'digest/md5'
library_path = ARGV[0]
hash = {}
Dir.glob(library_path + "/**/*", File::FNM_DOTMATCH).each do |filename|
next if File.directory?(filename)
puts 'Checking ' + filename
key = Digest::MD5.hexdigest(IO.read(filename)).to_sym
if hash.has_key? key
# puts "same file #{filename}"
hash[key].push filename
else
hash[key] = [filename]
end
end
hash.each_value do |filename_array|
if filename_array.length > 1
puts "=== Identical Files ===\n"
filename_array.each { |filename| puts ' '+filename }
end
end

No such file or directory?

Ruby is giving me this error:
C:/Ruby/new.rb:11:in `read': No such file or directory - m.txt (Errno::ENOENT)
from C:/Ruby/new.rb:11:in `<main>'
But I'm sure that there is such file, Here is my code:
text = File.read("m.txt").split('\n')
text.each do |x|
x.to_i
File.open("m.txt", "w") do |file|
file.gsub(x, x *10)
end
end
The line that is generating this error:
text = File.read("m.txt").split('\n')
I have checked several examples, like this: How can I read a file with Ruby?
And tried things like:
File.open("m.txt", "r+") do |infile|
while (line = infile.gets)
line.to_i.gsub(line, line *10)
end
end
But I'm still getting this error.
What I'm trying to do is: I have some numbers in text file like
12.2
432.3
3.43
.342
...
And I want to multiply each one by 10. Note I'm sure about the file and that it exists.
You have to provide the absolute path:
text = File.read("C:/Ruby/m.txt").split('\n')
since your current directory is not the same as your script's directory.
Alternatively, you should navigate to that specific folder and then run the script.
You can do it this way:
text = File.read("C:/Ruby/m.txt").split('\n')
File.open("C:/Ruby/m.txt", "w") do |file|
text.each do |x|
file.puts x.to_f * 10
end
end

Copying a file to a directory?

I have a Ruby program that copies a file from source folder to destination folder.
C:\srcdir\testfile.txt is the source folder, and C:\targetdir is the destination folder.
The program keeps reporting an error:
copy_files.rb:11:in block in <main>': uninitialized constant FileUtils (NameError)
Why is it? This is my code:
sourcedir = "C:\\srcdir"
targetdir = "C:\\targetdir"
Dir.foreach(sourcedir){
|f|
filepath = "#{sourcedir}\\#{f}"
if !(File.directory?(filepath)) then
if File.exist?("#{targetdir}\\#{f}") then
puts("#{f} already exists in target directory (not copied)")
else
FileUtils.cp(filepath, targetdir)
puts("Copying... #{filepath}")
end
end
}
FileUtils is a module, it isn't part of the Ruby core. You need to require it to use it, like this:
require 'fileutils'
This stackoverflow question explains how to move a file using FileUtils: How do I move a file with Ruby?
Here is the documentation for the FileUtils module for Ruby 1.9.3: http://ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html
This is untested code, but is closer how I'd write it:
SOURCEDIR = 'C:/srcdir'
TARGETDIR = 'C:/targetdir'
Dir.foreach(SOURCEDIR) do |f|
filepath = File.join(SOURCEDIR, f)
if !File.directory?(filepath)
if File.exist?(File.join(TARGETDIR, f)
puts "#{ f } already exists in target directory (not copied)"
else
print "Copying #{ filepath }... "
FileUtils.cp(filepath, TARGETDIR)
puts "done"
end
end
end
Of course, your OS would make it even easier; Batch and shell files and OS-level commands are made just for this.

Ruby Net::FTP gettextfile not able to save files locally

I am trying to retrieve files (.csv) from an ftp site and save them all locally in the same folder. My code looks like this:
#! /usr/bin/ruby
require 'logger'
require 'fileutils'
require 'net/ftp'
require 'rubygems'
require 'mysql2'
require 'roo'
require 'date'
# logging setup
log = Logger.new("/path_to_logs/ftp_log.log", 10, 1024000)
log.level = Logger::INFO
export_ftp_path = '/Receive/results/'
export_work_path ='/Users/pierce/results_exports/'
Net::FTP.open('host', 'username', 'password') do |ftp|
log.info("Logged into FTP")
ftp.passive = true
ftp.chdir("#{export_ftp_path}")
ftp.list.each do |file|
log.info("Found file #{file}")
new_file = file[56..115] #take part of the file name and remove spaces and periods
new_file = new_file.gsub(/[.]+/, "")
new_file = new_file.gsub(/\s/, "0")
ftp.gettextfile(file,"#{new_file}")
log.info("Downloaded file #{new_file}")
end
end
And here is the error I receive:
/Users/pierce/.rbenv/versions/1.9.2-p290/lib/ruby/1.9.1/net/ftp.rb:560:in `initialize': No such file or directory - (Errno::ENOENT)
from /Users/pierce/.rbenv/versions/1.9.2-p290/lib/ruby/1.9.1/net/ftp.rb:560:in `open'
from /Users/pierce/.rbenv/versions/1.9.2-p290/lib/ruby/1.9.1/net/ftp.rb:560:in `gettextfile'
from ftp_test.rb:44:in `block (2 levels) in <main>'
from ftp_test.rb:33:in `each'
from ftp_test.rb:33:in `block in <main>'
from /Users/pierce/.rbenv/versions/1.9.2-p290/lib/ruby/1.9.1/net/ftp.rb:116:in `open'
As suggested, here are the values I have for puts file and puts new_file.
file = -rwxr-xr-x 1 1130419 114727 9546 May 17 08:11 results_Wed. 16 May 2012.csv
new_file = results_Wed0230May02012csv
Any suggestions on what to change in gettextfile or within my script to get the files saved correctly?
You should use nlst instead of list when you just need a list of files in a directory. The output of list needs to be properly parsed otherwise.
When you request the file it has to be the original filename, including all spaces. When you save the file it can be anything you want (including spaces or not). The error was because you were requesting the wrong file. Use nlst in your case instead. It will make it much easier (no conversion or parsing needed).

Resources