I have a txt file and I want to extract only the first word of a line which contains the characters 'ath'.
File.open("myfile.txt").readlines.each do |line|
if line =~ /ath/
line.split.first
puts line
$line = line.chomp
puts "Ok"
else
nil
end
end
line.split.first only works if the first word of the line is a match, because when I do the same in irb:
"im here to ask someting easy".split.first
The output is 'im'.
If the first word in a line contains ath at any point
if line =~ /^\S*ath\S*/
Related
I'm very new to the Ruby world so please bear if its a simple query.
For one of my assignments, I'm looking to read the contents of all the text files in a folder (only top level) and redirect the file contents to a single output file in a appended or merged manner.
I'm a expecting a format like below:
Output File
File Name: 1st file name
all its contents
====================================
File Name: 2nd file name
all its contents
====================================
File Name: 3rd file name
all its contents
====================================
....
....
====================================
I managed to write the below script but the output file is empty. Any suggestions please.
File.open('C:\Users\darkop\Desktop\final_output.txt','a') do |final|
#files = Dir.glob("D:\text\*.txt")
for file in #files
text = File.open(file, 'r').read.sub(/#$/?\z/, $/)
text.each_line do |line|
puts "File Name:"#{file}
puts
final << line
puts "=" * 20
end
end
end
Also, is it possible to redirect the output in aforementioned format to a word document instead of a text file ?
Many thanks.
This should work.
The file name was empty because you have puts "File Name:"#{file}. This way #{file} doesn't get interpolated, because it isn't inside the double quotation marks.
Also, you didn't get the contents of the file because you just used puts, instead of puts line, which is what you want.
File.open('C:\Users\darkop\Desktop\final_output.txt','a') do |final|
#files = Dir.glob("D:\text\*.txt")
for file in #files
text = File.open(file, 'r').read.sub(/#$/?\z/, $/)
text.each_line do |line|
puts "File Name: #{file}"
puts
puts line
final << line
puts "=" * 20
end
end
end
-EDIT-
Since you are new to Ruby, it's better to use an each loop, instead of the for .. in loop. Also, just specify the output name with a .doc extension for a Word document.
File.open('C:\Users\darkop\Desktop\final_output.doc','a') do |final|
#files = Dir.glob("D:\text\*.txt")
#files.each do |file|
text = File.open(file, 'r').read.sub(/#$/?\z/, $/)
text.each_line do |line|
puts "File Name: #{file}"
puts
puts line
final << line
puts "=" * 20
end
end
end
I have a following file:
old_file
new_file
Some string.
end
Text in the middle that is not supposed to go to any of files.
new_file
Another text.
end
How using regex can I create two files with the following content:
file1
new_file
Some string.
end
file2
new_file
Another text.
end
How can I get information which is between keywords 'new_file' and 'end' to write it to the file?
If your files are not that large, you can read them in as a string, (use File.read(file_name)), and then run the following regex:
file_contents.scan(/^new_file$.*?^end$/m).select { |block| WRITE_TO_FILE_CODE_HERE }
See the regex demo
The ^new_file$.*?^end$ regex matches new_file that is a whole line content, then 0+ any characters as few as possible (incl. a newline as /m modifier is used), and then end (a whole line).
Else, you may adapt this answer here as
printing = false
File.open(my_file).each_line do |line|
printing = true if line =~ /^new_file$/
puts line if printing
printing = false if line =~ /^end$/
end
Open the file when the starting line is found, write to it where puts line is in the example above, and close when printing false occurs.
You can also read the file chunk by chunk by changing what constitutes a "line" in ruby:
File.open("file1.txt", "w") do |file1|
File.open("file2.txt", "w") do |file2|
enum = IO.foreach("old_file.txt", sep="\n\n")
file1.puts enum.next.strip
enum.next #discard
file2.puts enum.next.strip
end #automatically closes file2
end #automatically closes file1
By designating the separator as "\n\n" ruby will read all the characters up to and including two consecutive newlines--and return that as a "line".
If that kind of format is fixed, then you may try this (new_file\n.*\nend)
I understand how to open and then print the content of the file. I would like to understand how to ask a second question on a new line after the txt file has been printed.
The code below prints the output of the text file, then on the same line, asks "Type the file name again:"
filename = ARGV.first
txt = open(filename)
puts "Here's your file #{filename}:"
print txt.read
print "Type the filename again: "
file_again = $stdin.gets.chomp
txt_again = open(file_again)
print txt_again.read
I would like this question to be printed on a new line after the txt file has been read.
You should use puts and not print.
The difference is that puts add a new line at the end of the output.
filename = ARGV.first
txt = open(filename)
puts "Here's your file #{filename}:"
puts txt.read // Changed Line
print "Type the filename again: "
file_again = $stdin.gets.chomp
txt_again = open(file_again)
puts txt_again.read //Changed Line
How can I avoid a new line when I use puts line + "test"
Example code:
File.open("test.txt", "r") do |f|
f.each_line do |line|
puts line + "test" #=>line1\ntest
#puts "test" + line #=> testline1
end
end
When I use:
puts "test" + line`
It shows:
testline1
(line1 being the only thing in the test.txt)
However,
puts line + "test"
looks like:
test
line1
Is there anyway of stopping it from producing the extra line?
If you want to strip out the newline, use String#chomp to take care of it.
http://apidock.com/ruby/v1_9_3_392/String/chomp
puts line.chomp + "test"
Use String#strip to strip out all the leading and trailing whitespace characters (including new line):
puts line.strip + "test"
# => line1test
To delete only the trailing whitespaces, you can use String#rstrip:
puts line.rstrip + "test"
# => line1test
I'm learning Ruby and have failed to make a compound 'if' statement work. Here's my code (hopefully self explanatory)
commentline = Regexp.new('^;;')
blankline = Regexp.new('^(\s*)$')
if (line !~ commentline || line !~ blankline)
puts line
end
the variable 'line' is gotten from reading the following file:
;; alias filename backupDir
Prog_i Prog_i.rb ./store
Prog_ii Prog_ii.rb ./store
This fails and I'm not sure why. Basically I want the comment lines and blank lines to be ignored during the processing of the lines in the file. Thanks for your help.
you need to use an AND
basically you want not (blank or comment) which turns into not blank and not comment after applying DeMorgan
if (line !~ commentline && line !~ blankline)
puts line
end
or
unless(line ~= commentline || line ~= blankline)
puts line
end
depending on which you find more readable
You can write this much more terse, as
puts DATA.readlines.reject{|each|each =~ /^;;|^\s*$/}
__END__
;; alias filename backupDir
Prog_i Prog_i.rb ./store
Prog_ii Prog_ii.rb ./store
This is your code:
commentline = Regexp.new('^;;')
blankline = Regexp.new('^(\s*)$')
if (line !~ commentline || line !~ blankline)
puts line
end
and how I'd write the same thing:
[
';; alias filename backupDir',
'',
'Prog_i Prog_i.rb ./store',
'Prog_ii Prog_ii.rb ./store'
].each do |line|
puts line if (!line[/^(?:;;)?$/])
end
Which outputs:
;; alias filename backupDir
Prog_i Prog_i.rb ./store
Prog_ii Prog_ii.rb ./store