Within our file structure we have snippets with tags. From my project directory, I want to return the snippet name based on the tag declared on the preceding line, for all files ending in .feature within the project.
For example, the directory contains a login.feature file with the following text:
#integration #unit #smoke
Scenario: Login to Product
#integration #unit
Scenario: Buy Stuff
The directory also contains a logout.feature file with the following text:
#test #wip #smoke
Scenario: Logout of Product
I want to run a single command that returns the following array:
["Login to Product", "Logout of Product"]
As you can see, I'm essentially doing the following:
grep -inr -A 1 '#smoke' ./my/directory | grep Scenario | sed -n -e 's/^.*Scenario: //p' | awk '!seen[$0]++'
...with the exception of converting the resulting lines into an array.
Is there an elegant way to do this in Ruby? Or can I somehow combine the Unix magic with Ruby sugar? Or should I stick to sed/awk/grep?
Here's what I came up with
results = []
Dir.glob("#{folder}/**/*.feature").each do |file|
i = 0; line = nil
File.foreach(file).map{ |l| line = i+1 if l[/#smoke/]; i+=1 }
results << IO.readlines(file)[line].gsub(/Scenario:\s|\n/,'') unless line.nil?
end
p results
The Results:
["Login to Product", "Logout of Product"]
You can easily shift this into a method.
Edit: Updated this after re-examining your full command line. Looks like you only want the Scenario that comes AFTER a #smoke line and no other Scenarios should be included in the output.
Related
File1.log:
Result for scripts as follows {"Script 1"=>{"expected"=>"Pass", "actual"=>"Pass", "result"=>true},
"Script 2"=>{"expected"=>"Fail", "actual"=>"Pass", "result"=>false}
-----
-----
-----
-----
Result for scripts as follows {"Script 3"=>{"expected"=>"Pass", "actual"=>"Pass", "result"=>true}, "Script 4"=>{"expected"=>"Fail", "actual"=>"Pass", "result"=>false}
File2.log:
Result for scripts as follows {"Script 1"=>{"expected"=>"Pass", "actual"=>"Pass", "result"=>true}, "Script 2"=>{"expected"=>"Pass", "actual"=>"Pass", "result"=>true}
I will have to parse the .log files which will contain multiple lines and get the above given lines alone.
The only thing common to be used to get this is the first text: Result for scripts as follows.
Any suggestions to solve this using Ruby or any powershell commands?
In short, you need to traverse each log file line by line, perform a pattern match and print the results.
The below code should solve your problem
# my log files are in my current working directory
log_files = Dir["./*.log"]
false_matches = []
log_files.each do |x|
puts "\n#{x}\n==========\n"
f = File.open(x,"r")
f.each_line do |line|
false_matches.push(line.scan(/"Script \d*"=>{"expected"=>".{4}", "actual"=>".{4}", "result"=>false/))
end
puts "\n"
f.close()
end
false_matches.each do |x|
unless x.length == 0
puts x[0].scan(/Script \d*/)
end
end
I've received a list of emails that I'd like to run an email campaign on, however, in the list there are some URL's... and it complicates things.
Here's the standard formatting of the email address, for example:
news#ydr.com
I'd like to paste the list in terminal and run a command to ONLY capture all of the email addresses and save them to a file and remove any URLS.
Please advise! It is much appreciated :)
If you are just looking to catch most emails this regex might work.
I got this regex from here How to validate an email address using a regular expression?
They talk about the much more complicated RFC822 email regex
#!/usr/bin/env ruby
input = $stdin.readlines # ctrl + D after paste
input.each do |f|
puts f if f[/^[a-zA-Z0-9_.+\-]+#[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-.]+$/]
end
# test input
# foo#bar.com
# www.cnn.com
# test.email#go.com
# turdburgler#mcdo.net
# http://www.google.com
To write emails to a file:
#!/usr/bin/env ruby
file = File.open("emails.txt", "w")
input = $stdin.readlines # ctrl + D after paste
input.each do |f|
file.write(f) if f[/^[a-zA-Z0-9_.+\-]+#[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-.]+$/]
end
file.close
Just to be clear, this is a ruby script which should be ran like this.
Save the script as a file, ie email_parser.rb.
chmod +x email_parser.rb
./email_parser.rb # this will wait for stdin, here you paste the list in to the terminal
When the terminal is hanging waiting, paste the list of emails in, then press ctrl + D to tell the program that this is the EOF. The program will then run through the list of emails/urls and parse. The output of this will be a file if using the updated script. The file will be in the same folder you ran the script and be called emails.txt
I am trying to import a file using ruby and parse it. Is there a way to read the next line once inside the file import? Basically I want to see if a specific line is within x lines of another important line. Like does "x phrase" Come within 10 lines of "y phrase". I don't see a way to do this -- I know its simple with Java.
Thanks!
You can also try:
web_contents = "c:\\path\\to\\your\\file.txt"
File.open(web_contents).each_with_index do |line, i|
line.chomp!
puts "line #{line}, i #{i}" # Do whatever you want to here
end
The .each_with_index method gives you an index, i, which you can use to keep track of where on what line in your file you are. Simple maths can then yield the offset as required.
To read lines of a file
lines_array = IO.readlines('testfile')
lines_array.each { |l| #Do your stuff with your line }
VoilĂ
Ruby Docs on IO
In my Rails app I am trying to collect the paths to all the files contained in two different directories using Dir.glob.
The following code works but is not very concise. Isn't there a way two match two patterns at once with Dir.glob?
common_file_paths = Dir.glob("app/assets/mystuff/*").reject do |path|
File.directory?(path)
end
more_file_paths = Dir.glob("app/assets/mystuff/more/*").reject do |path|
File.directory?(path)
end
file_paths = common_file_paths + more_file_paths
Dir.glob also accepts an array of patterns.
Dir.glob(["app/assets/mystuff/*", "app/assets/mystuff/more/*"])
this should do it for you .. tested it in my local machine and it works as expected.
lets say , you have the following directory and subdirectory :
z$ find deletpractic/
deletpractic/
deletpractic/sub_dir
deletpractic/sub_dir/file1_in_subdir.txt
deletpractic/sub_dir/file2_in_subdir.txt
deletpractic/text1
deletpractic/text2
deletpractic/text3
deletpractic/text4
deletpractic/text5
deletpractic/text6
deletpractic/text7
it pretty much boils down to this Dir.glob("/mydir/**/*")
[za]$ /usr/bin/ruby -rpp -e 'common_file_paths = Dir.glob("/dev/deletpractic/**/*").reject do |path| File.directory?(path) end ; pp common_file_paths'
Output :
["/dev/deletpractic/sub_dir/file1_in_subdir.txt",
"/dev/deletpractic/sub_dir/file2_in_subdir.txt",
"/dev/deletpractic/text1",
"/dev/deletpractic/text2",
"/dev/deletpractic/text3",
"/dev/deletpractic/text4",
"/dev/deletpractic/text5",
"/dev/deletpractic/text6",
"/dev/deletpractic/text7"]
I have a command that formats it's output in the form of CSV. I have a list of machine this command will run against using a foreach loop. in the below example $serverlist is automatically generated with an AD Query.
foreach ($server in $serverlist) {
$outputlist = mycommand
}
what I would like to do is somehow end up with objects from the resulting CSV so I can then only select certain objects for a report. However the only way I can see to do this is using import-csv, which only seems to want to work with files and not variable: ie.
Import-Csv output.csv | ft "HostName","TaskName" |
Where-object {$_.TaskName -eq 'Blah'}
I'd like to be able to have import-csv $outputlist instead. doing this causes import-csv to have a hissyfit :)
Can anyone point me in the right direction on how to achieve this?
Cheers
The command you want is called ConvertFrom-CSV. The syntax is shown below.
NAME
ConvertFrom-CSV
SYNOPSIS
Converts object properties in comma-separated value (CSV) format into CSV
versions of the original objects.
SYNTAX
ConvertFrom-CSV [[-Delimiter] <char>] [-InputObject] <PSObject[]> [-Header <string[]>] [<CommonParameters>]
ConvertFrom-CSV -UseCulture [-InputObject] <PSObject[]> [-Header <string[]>] [<CommonParameters>]