0

I have a script that combs through a particular folder and finds all of the documents that have been modified today:

Dir.glob("/path/to/folder/*/*.txt") do |file|
    f = File.open(file.strip)
    lines = f.readlines
    mod = f.mtime
    modtime = f.mtime.strftime("%I:%M%p")
    text = lines.join
    wordcount = text.split.length
    project = File.basename(file).gsub(/.txt/, ' ').strip
    if mod > (Time.now - 86400)
        found_completed = true
        entry = "#{modtime} - #{project} - #{wordcount}"
    end
    if found_completed == false
    puts "not today"
    end
    if found_completed == true
    puts "worked on #{entry}"
    end
end

That all works fine. However, I also went to write that multi-line output to a file. When I add this to the end of the script (before the final 'end') it comes up blank:

open('/path/to/newfile.txt', 'w') { |f|
  f.puts ("#{entry}" + "/n/n") }

Any help would be appreciated.

2 Answers 2

1

Just change variable name f to ff, and do:

entry = nil
if mod > (Time.now - 86400)
   found_completed = true
   entry = "#{modtime} - #{project} - #{wordcount}"
end
open('/path/to/newfile.txt', 'a+') {|ff| ff.puts entry }

or:

if mod > (Time.now - 86400)
   found_completed = true
   entry = "#{modtime} - #{project} - #{wordcount}"
   open('/path/to/newfile.txt', 'a+') {|ff| ff.puts entry }
end

To open file for write/read operations, and then to use it, do:

fstore = open '/path/to/newfile.txt', 'a+'
...
fstore.puts entry
...
fstore.close
Sign up to request clarification or add additional context in comments.

5 Comments

This seems really close. However, if I use suggestion 2, I only the get the last entry if there are multiple positives in the glob search. On suggestion 1, I'm still getting a blank output for #{entry}.
I think DGM's answer has something to do with this as well. Changed mode to a+, however now I am getting blank lines for files that don't match the "if" criteria. Is there a way to end the glob loop and still pass #{entrytext}? Or eliminate the blank lines?
"#{entry}\n\n" this do a single blank line, do you need them?
I would just like to skip a line between actual entries
I still don't like opening the file every time through the loop, that's a horrible way do this.
1

You are opening the file every time through the glob loop, overwriting the file, and the last file processed yields a blank entry?

You probably want to surround the glob with the file opening, so it only gets opened once, putting the f.puts line where it is now.

edit

This is a little more idiomatic ruby... break it up into a class, keep the parts small and isolated in meaning, give it intention revealing function names. I'm sure there's more to be done, but I think this makes it easier to read.

class FileInfo
  def initialize(file)
    @file = File.open(file)
  end

  def wordcount
    @file.read.scan(/\w/).size
  end

  def mtime
    @file.mtime
  end

  def formatted_mtime
    @file.mtime.strftime("%I:%M%p")
  end

  def project
    File.basename(@file.path).gsub(/.txt/, ' ').strip
  end

  def recent?
    @file.mtime > (Time.now - 86400)
  end
end

open('logfile.txt', 'w')  do |log|
  Dir.glob("/path/to/folder/*/*.txt") do |file|
    fi = FileInfo.new(file)
    if fi.recent?
      log.puts "worked on #{fi.formatted_mtime} - #{fi.project} - #{fi.wordcount}"
    else
      log.puts "not today"
    end
  end
end

2 Comments

Good suggestion. But now that yields an error: "in `write': closed stream (IOError)"
did you surround the whole loop?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.