Changing Directory by Ruby - ruby

I am trying to create a simple script to delete all the files from my Desktop(I am using Ubuntu).
puts "Started at #{Time.now}"
Dir.chdir("/Desktop")
Dir.entries(".").each do |file|
if file.to_s.include?("xlsx")
puts "Deleting file #{file}" unless file == "." || file == ".."
File.delete "#{Dir.pwd}/#{file}" unless file == "." || file == ".."
end
end
puts "Ended on #{Time.now}"
But when I generate the code it throws the below error:
chdir': No such file or directory # dir_chdir - /Desktop
(Errno::ENOENT)
What I am doing wrong?

puts "Started at #{Time.now}"
Dir.chdir("#{ENV['HOME']}/Desktop")
Dir.entries(".").select { |file| file.ends_with?('.xlsx') }.each do |file|
puts "Deleting file #{file}"
File.delete "#{Dir.pwd}/#{file}"
end
puts "Ended on #{Time.now}"

Related

Upload files from local directory to SFTP using Ruby

For some reason SFTP upload in Ruby (copy files from local directory to SFTP server) doesn't seem to work. I'm currently using Ruby 2.5.3. I would really appreciate any ideas :
My code below:
require 'net/ssh'
require 'net/sftp'
server = 'sftp.secure.net'
username = '123456'
password = "Mypassword*"
uid = '123456'
files = Dir.entries(outdir)
Net::SFTP.start(server, username, :password=>password) do |sftp|
for filename in files
#puts files
puts "Browsing files..."
puts "File: #{filename}"
#puts new_filename
####### replacing , for | ########
if /#{uid}_test_[0-9]{8}_[0-9]{8}.txt$/ =~ filename
file = "#{outdir}\\#{filename}"
puts "SFTPing #{file}"
sftp.upload(file)
puts "SFTP Complete for file #{file}"
puts "Cleanup"
puts "Deleting #{file}."
File.delete(file)
puts "Files were deleted."
end
end
puts "Closing SFTP connection..."
sftp.close
puts "SFTP connection closed."
end
Thank you Kennycoc! That upload! was definitely helpful. Also, sftp.close() should be deleted for sftp. The SFTP connection automatically close. This is needed for FTP I found out, but not for SFTP.
Thanks!
Finalized Version:
files = Dir.entries(outdir)
Net::SFTP.start(hostname, username, :password=>password) do |sftp|
for filename in files
#puts files
puts "Browsing files..."
puts "File: #{filename}"
#puts new_filename
####### replacing , for | ########
if /#{uid}_test_[0-9]{8}_[0-9]{8}.txt$/ =~ filename
file = "#{outdir}\\#{filename}"
puts "SFTPing #{file}"
sftp.upload!(file)
puts "SFTP Complete for file #{file}"
puts "Cleanup"
puts "Deleting #{file}."
File.delete(file)
puts "Files were deleted."
end
end
#puts "Closing SFTP connection..."
#sftp.close()
puts "SFTP connection closed."
end
SFTP is an entirely different protocol based on the network protocol SSH (Secure Shell).
Read SFTP vs. FTPS: The Key Differences
.
Use gem net-sftp.
Ex:
require "net/sftp"
Net::SFTP.start("host", "username", :password: "password") do |sftp|
#from your system(local)
sftp.upload!("/path/to/local", "/path/to/remote")
# through URL
open(your_file_url) do |file_data|
sftp.upload!(file_data, /path/to/remote)
end
end

Remove a string from a Ruby file when it matches a regex

I'm writing a little script in Ruby that removes comments from Ruby files:
#!/usr/bin/ruby
def uncomment(file)
File.readlines(file).each do |line|
if line =~ /(^\s*#|^\t*#)(?!\!).*/
puts line + " ==> this is a comment"
#todo: remove line from the file
end
end
end
puts "Fetching all files in current directory and uncommenting them"
# fetching all files
files = Dir.glob("**/**.rb")
# parsing each file
files.each do |file|
#fetching each line of the current file
uncomment file
end
I am stuck on how to remove these lines that match the regex in the #todo section, it would be great if someone could help!
change:
def uncomment(file)
File.readlines(file).each do |line|
if line =~ /#(?!\!).+/
puts line + " ==> this is a comment"
#todo: remove line from the file
end
end
end
to:
def uncomment(file)
accepted_content = File.readlines(file).reject { |line| line =~ /#(?!\!).+/ }
File.open(file, "w") { |f| accepted_content.each { |line| f.puts line } }
end
You would be reading the accepted lines into an array(accepted_content), and writing back that array into the file
I would do this by creating a temporary file:
open('tmp', 'w') do |tmp|
File.open(file).each do |line|
tmp << line unless line =~ /#(?!\!).+/
end
end
File.rename('tmp', file)

Ruby cannot open file ( Errno::ENOENT ) but the same path can be opened from IRB

I have a simple Ruby script that is building a list of files from an array of strings, so I have a method a bit like this:
def initialize( rootpath, name )
#content = ""
intermission = ""
if ( ! (rootpath[-1] == "/" || name[0] == "/" ))
intermission="/"
end
#path= "#{rootpath}#{intermission}#{name}"
print "Open JavascriptFile from #{#path}"
if (! File.exists? #path)
print "File does not exist!"
end
File.open( #path ).each do |line|
#content << line
end
end
This is called along the lines of:
files= ['alice.js', 'bob.js', 'claire.js', 'dave.js']
basepath= "/home/glenatron/projects/myJSProject/"
files.each do |filename|
myLoader.new( basepath, filename )
end
When I load in my classes from IRB and run this I get:
Open JavascriptFile from /home/glenatron/projects/myJSProject/alice.js
File does not exist!
Errno::ENOENT: No such file or directory - /home/glenatron/projects/myJSProject/alice.js
As I understand it, this means that the file does not exist.
However not only does the file definitely exist, in IRB I can paste the exact same path and see it's content - a simple File.open("/home/glenatron/projects/myJSProject/alice.js").each { | line | print line } reveals the complete content of the file. So why can I do this from a direct command line request and not from my Ruby class? Is it trying to read a local path instead of the full path I am passing it?
Guard the File.open .. lines with else block:
if (! File.exists? #path)
print "File does not exist!"
else # <---
File.open( #path ).each do |line|
#content << line
end
end # <----
or return earlier in the if block:
if (! File.exists? #path)
print "File does not exist!"
return
endif
Otherwise, the code always try to open the file, even if it does not exist.
Use File::join to join the path components:
File.join("/home/glenatron/projects/myJSProject/", "alice.js")
# => "/home/glenatron/projects/myJSProject/alice.js"
File.join("/home/glenatron/projects/myJSProject", "alice.js")
# => "/home/glenatron/projects/myJSProject/alice.js"
Edit to bring the solution ( in the comments ) into the answer:
To find the exact path, use p #path - this revealed that the path that was trying to open looked like this when it failed: /home/glenatron/projects/myJSProject/alice.js\r which was causing the problem. A simple #path.strip! resolved it once this was clear.
From your code shown in the question,
looks like an end instead of an else, e.g.
if (! File.exists? #path)
print "File does not exist!"
end # <------------ This wasn't valid
File.open( #path ).each do |line|
#content << line
end
end
should be
if (! File.exists? #path)
print "File does not exist!"
else
File.open( #path ).each do |line|
#content << line
end # THIS end is valid as it ends a `.each` block
end

Ruby symlink not working in OS X

The following script creates symlinks as expected, but the original file can never be found. Can someone tell me why? They appear to be valid symlinks because they register as aliases in OS X and File.symlink? returns true once they have been created.
#!/usr/bin/env ruby
case ARGV.first when 'link'
file = ARGV[1]
if !File.exist?(file)
puts "Unfortunately, \"#{file}\" was not found."
exit 0
end
bin = "/usr/local/bin/"
if !File.directory?(bin)
puts "#{bin} does not exist!"
puts "creating #{bin}..."
system "mkdir -p #{bin}"
end
if File.extname(file).empty?
if File.symlink?(bin + file)
puts "Unfortunately, \"#{bin + file}\" already exists."
exit 0
end
name = bin + file
puts "Symlinking #{file} to #{name}..."
File.symlink(file, name)
system "chmod +x #{name}"
else
name = file.split(File.extname(file))
name = bin + name.first
if File.symlink?(name)
puts "Unfortunately, \"#{name}\" already exists."
exit 0
end
puts "Symlinking #{file} to #{name}..."
File.symlink(file, name)
system "chmod +x #{name}"
end
else
puts "try: bin link <file>"
end
The script is run in the following way:
ruby script.rb link myfile.rb
To answer my own question, replacing the instances of
File.symlink(file, name)
with
File.symlink(File.expand_path(file), name)
worked perfectly.

Open a document in a Mac app with a rake file

I have a task in my Rakefile for creating a new post in Jekyll. (I borrowed it from Octopress).
I've tried to hack it so that it will create a new markdown file, add the default header info and then open it in IA Writer. It creates the file and adds the info, but what it opens isn't the file. It looks like the filename variable isn't being passed through to the system command, but I have no idea how I should be writing it.
Here's the code:
# Usage rake new_post['Title of the Post']
desc "Beginning a new post in _posts"
task :new_post, :title do |t, args|
args.with_defaults(:title => 'new-post')
title = args.title
filename = "_posts/#{Time.now.strftime('%Y-%m-%d')}-#{title.to_url}.markdown"
open_filename = "#{Time.now.strftime('%Y-%m-%d')}-#{title.to_url}.markdown"
if File.exist?(filename)
abort("rake aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
end
puts "Creating new post: #{filename}"
open(filename, 'w') do |post|
post.puts "---"
post.puts "layout: post"
post.puts "title: \"#{title.gsub(/&/,'&')}\""
post.puts "date: #{Time.now.strftime('%Y-%m-%d %H:%M')}"
post.puts "categories: "
post.puts "---"
end
puts "Opening: #{filename}"
system('open -a IA\ Writer ~/Dropbox/Archive/jdb/#{filename}')
end
In line system... change ' to ". In ' ruby doesn't use variables, example:
001 > filename = "test"
=> "test"
002 > puts '#{filename}'
=> #{filename}
003 > puts "#{filename}"
=> test

Resources