I am using the ruby Dir method to get all the filenames within a directory. Like this:
dir_files = Dir["/Users/AM/Desktop/07/week1/dailies/regionals/*.csv"]
This gives me an array with each element listed below:
/Users/AM/Desktop/07/week1/dailies/regionals/ch002.csv
/Users/AM/Desktop/07/week1/dailies/regionals/ch014.csv
/Users/AM/Desktop/07/week1/dailies/regionals/ch90.csv
/Users/AM/Desktop/07/week1/dailies/regionals/ch112.csv
/Users/AM/Desktop/07/week1/dailies/regionals/ch234.csv
Im trying to extract just the part of the above strings that matches: "regionals/*.csv"
How do I do that in Ruby?
The following didn't work
#files_array.each do |f|
f = f.split("/").match(/*.csv/)
i = f.include?(".csv")
puts "#{i.inspect}"
#self.process_file(f[i])
end
Whats a clever way of doing this? I intend to pass the returned string of each filename to a helper method for processing. But as you can see all the csv files are located in a different directory as my executing script.
My script thats executing this is located at
/Users/AM/Desktop/07/week1/dailies/myScript.rb
Thanks
This will always post back the final directory and file name, regardless of the file pattern:
#files_array.map { |f| f.split("/")[-2..-1].join("/") }
#=> ["regionals/ch002.csv", "regionals/ch014.csv", "regionals/ch90.csv", "regionals/ch112.csv", "regionals/ch234.csv"]
This gives you the desired values :)
dir_files.map {|path| path[/regionals\/.*.csv/]}
#=> ["regionals/ch002.csv", "regionals/ch014.csv", "regionals/ch90.csv", "regionals/ch112.csv", "regionals/ch234.csv"]
Related
I am are receiving an array as a variable
Is an example
["/a/b/01_Sources/02_Transferred/06_CPAS/Redbull/from_MediaHouse/Transcripts/MI201711200143.xlsx", "/a/b/01_Sources/02_Transferred/06_CPAS/Redbull/from_MediaHouse/Transcripts/MI201703030110.pdf"]
The following statement creates this list:
<%= var(file_list_array).map{|file| "<li>#{File.basename(file)}</li>"}.join("\n")%>
MI201711200143.xlsx
MI201703030110.pdf
The following statement creates this list
<%= var(file_list_array).map{|file| "<li>#{file}</li>"}.join("\n")%>
/a/b/01_Sources/02_Transferred/06_CPAS/Redbull/from_MediaHouse/Transcripts/MI201711200143.xlsx
/a/b/01_Sources/02_Transferred/06_CPAS/Redbull/from_MediaHouse/Transcripts/MI201703030110.pdf
But what I would really like:
/Redbull/from_MediaHouse/Transcripts/MI201711200143.xlsx
/Redbull/from_MediaHouse/Transcripts/MI201703030110.pdf
What do I need to change to get that ?
Assuming you have your array of file paths in an array you could do.
file_paths.map{|path| path.gsub(/.*(\/Redbull\/.*)/, $1) }
This will replace each item with whatever is below the "Redbull" directory
Alternatively if you didn't want to preprocess that list you could just put it in your display code, but that will make it less clear as to what you need to send the displaying logic.
<%= var(file_list_array).map{|file| "<li>#{file.gsub(/.*(\/Redbull\/.*)/, $1)}</li>"}.join("\n")%>
Try this
file_list_array[0].split("06_CPAS")[1]
assuming you want to split from "06_CPAS" . You can pass it as a variable too like this
split_str = "06_CPAS"
index = 0
file_list_array[index].split(split_str)[1]
I am very new to ruby. I am able to connect to AWS S3 using ruby. I am using following code
filePath = '/TMEventLogs/stable/DeviceWiFi/20160803/1.0/20160803063600-2f9aa901-2ce7-4932-aafd-f7286cdb9871.csv'
s3.get_object({bucket: "analyticspoc", key:"TMEventLogs/stable/DeviceWiFi/20160803/1.0/"}, target:filePath ) do |chunk|
puts "1"
end
In above code s3 is client. "analyticspoc" is root bucket. My path to csv file is as follows All Buckets /analyticspoc/TMEventLogs/stable/DeviceWiFi/20160803/1.0/20160803063600-2f9aa901-2ce7-4932-aafd-f7286cdb9871.csv.
I have tried above code. I above code I was getting error Error getting objects: [Aws::S3::Errors::NoSuchKey] - The specified key does not exist. Using above code I want to read the contents of a file. How to do that ? Please tell me what is the mistake in above code
Got the answer. You can use list_objects for accessing array of file names in chunk(1000 at a time) where as get_object is used for accessing the content of a single file as follows
BUCKET = "analyticspoc"
path = "TMEventLogs/stable/DeviceWiFi/20160803/1.0/"
s3.list_objects(bucket:BUCKET, prefix: path).each do |response|
contents = response.contents
end
file_name = "TMEventLogs/stable/DeviceWiFi/20160803/1.0/012121212121"
response = s3.get_object(bucket: BUCKET, key: file_name)
As far as I can tell you're passing in the arguments incorrectly. It should be a single options hash according to the documentation for get_object:
s3.get_object(
bucket: "analyticspoc",
key: "TMEventLogs/stable/DeviceWiFi/20160803/1.0/",
target: filePath
) do |chunk|
puts "1"
end
I believe it was trying to use your hash as a string key which is obviously not going to work.
With Ruby the curly braces { } are only necessary in method calls if additional arguments follow that need to be in another hash or are non-hash in nature. This makes the syntax a lot less ugly in most cases where options are deliberately last, and sometimes first and last by virtue of being the only argument.
I have a text file (objects.txt) which contains Objects and its attributes.
The content of the file is something like:
Object.attribute = "data"
On a different file, I am Loading the objects.txt file and if I type:
puts object.attribute it prints out data
The issue comes when I am trying to access the object and/or the attribute with a string. What I am doing is:
var = "object" + "." + "access"
puts var
It prints out object.access and not the content of it "data".
I have already tried with instance_variable_get and it works, but I have to modify the object.txt and append an # at the beginning to make it an instance variable, but I cannot do this, because I am not the owner of the object.txt file.
As a workaround I can parse the object.txt file and get the data that I need but I don't want to do this, as I want take advantage of what is already there.
Any suggestions?
Yes, puts is correctly spitting out "object.access" because you are creating that string exactly.
In order to evaluate a string as if it were ruby code, you need to use eval()
eg:
var = "object" + "." + "access"
puts eval(var)
=> "data"
Be aware that doing this is quite dangerous if you are evaluating anything that potentially comes from another user.
Im sure this is very obvious but I cant seem to get it work.
I have a Pathname instance and Im attempting to remove the first directory from it and then return the rest of the string, but because slice returns the part removed it seems there is no way of getting the smaller string back.
filepath = Pathname.new("this_folder_needs_to_go/another_folder/file.html")
filedir = filepath.to_s.slice("this_folder_needs_to_go/")
newfilepath = filedir
I would hope newfilepath would be another_folder/file.html but instead it just returns this_folder_needs_to_go/
So how on earth to I get the string that has had the part removed?
Using String#split:
"this_folder_needs_to_go/another_folder/file.html".split('/', 2)[1]
# => "another_folder/file.html"
You can also use .slice! instead of .slice if you're trying to modify your string
filepath = Pathname.new("this_folder_needs_to_go/another_folder/file.html")
filepath.to_s.slice!("this_folder_needs_to_go/")
puts filepath ==> "another_folder/file.html"
Though that will affect your filepath variable irreversibly.
#partition will also work in a similar manner to #split
filepath = Pathname.new("this_folder_needs_to_go/another_folder/file.html")
file_dir = filepath.partition("this_folder_needs_to_go/")[-1]
file_dir
#=> "another_folder/file.html"
#partition returns [head,sep,tail] so this will look like ["","this_folder_needs_to_go","/another_folder/file.html"] the [-1] says get the last element.
I'm using the following to open a file within a directory that contains 'abc' in the filename. The wildcard is used as the rest of the filename includes a timestamp (time and date the file was created).
required = ["this", "two"]
log = Dir['*.log'].select { |f| f.include?('abc')}
result = required.all? do |phrase|
log.any? { |line| line.include?(phrase) }
end
index = result ? "Pass" : "Fail"
The above script is part of an automation process, so the full name will not be known (file created in one of the initial steps)
Is there a way to sort files by mtime prior to the .select?
I've tried .sort and .max_by prior to .select and get private method error
log = Dir['*.log'].max_by {|f| File.mtime(f)}.select { |f| f.include?('abc')}
I've tried it after .select, which gets the latest file but throws and underfined method 'any?' - this seems incorrect anyway as i should be sorting before selecting.
any assistance would be appreciated
#max_by is going to return at most one element. You should be able to use #sort_by to arrange the files according to their mtimes, #reverse this list, and then use #find (or its alias #detect) to pluck out the first element matching the predicate ({ |f| f[/abc/] }, in this case).