Looking for a way to recursively for a string array through directories and subdirectories

I can get this to work but only in the directory that the script resides
in.
If i change the dir_path to a different directory it says that the file
its trying to read is a directory.
Any help would be welcome...

dir_path = '.'
str = /somearray|with|logts|of|strings/

# Searching for string
Dir.chdir(dir_path) do
  Dir.glob("*") do |filename|
    IO.foreach(filename) do |line|
      if line =~ str
        puts "#{filename}: #{line} "
        puts "--------------------------------------------------"
        logger = Logger.new($stdout)
    end
  end
end

···

--
Posted via http://www.ruby-forum.com/.

Try using Dir['**/*.*']

···

--
Posted via http://www.ruby-forum.com/.

The way you've called Dir.glob, it can easily return directories as well as plain files. Joel's response is a good one, but it can still return terminal directories that are empty.

Even doing Dir['**/*'] will get you more than you bargained for.

Example: set up a quick demo:

tamara@pontiki:~:2013-09-13@07:07:42
$ cd /tmp

tamara@pontiki:/tmp:2013-09-13@09:37:29
$ mkdir -p test/recursive/dirs.ext

tamara@pontiki:/tmp:2013-09-13@09:37:50
$ ls -al test
total 0
drwxr-xr-x 3 tamara wheel 102B Sep 13 21:37 ./
drwxrwxrwt 17 root wheel 578B Sep 13 21:37 ../
drwxr-xr-x 3 tamara wheel 102B Sep 13 21:37 recursive/

tamara@pontiki:/tmp:2013-09-13@09:38:02
$ ls -alR test
total 0
drwxr-xr-x 3 tamara wheel 102B Sep 13 21:37 ./
drwxrwxrwt 17 root wheel 578B Sep 13 21:37 ../
drwxr-xr-x 3 tamara wheel 102B Sep 13 21:37 recursive/

test/recursive:
total 0
drwxr-xr-x 3 tamara wheel 102B Sep 13 21:37 ./
drwxr-xr-x 3 tamara wheel 102B Sep 13 21:37 ../
drwxr-xr-x 2 tamara wheel 68B Sep 13 21:37 dirs.ext/

test/recursive/dirs.ext:
total 0
drwxr-xr-x 2 tamara wheel 68B Sep 13 21:37 ./
drwxr-xr-x 3 tamara wheel 102B Sep 13 21:37 ../

tamara@pontiki:/tmp:2013-09-13@09:38:13
$ touch test/recursive/file

tamara@pontiki:/tmp:2013-09-13@09:39:34
$ touch test/recursive/file_with.ext

Then:

[104] pry(main)> Dir['/tmp/test/**/*'].inject({}){|m,o| m[o]=File.ftype(o);m}
=> {"/tmp/test/recursive"=>"directory",
"/tmp/test/recursive/dirs.ext"=>"directory",
"/tmp/test/recursive/file"=>"file",
"/tmp/test/recursive/file_with.ext"=>"file"}
[105] pry(main)> Dir['/tmp/test/**/*.*'].inject({}){|m,o| m[o]=File.ftype(o);m}
=> {"/tmp/test/recursive/dirs.ext"=>"directory",
"/tmp/test/recursive/file_with.ext"=>"file"}
[106] pry(main)>

So in your code, it will fail if you try IO.foreach on a directory

A simple enough rewrite:

def grep_r(search_criteria, starting_directory='.')
  raise "Search criteria must be a regular expression" unless search_criteria.kind_of? Regexp
  raise "Starting point not a directory" unless File.directory? starting_directory
  Dir[FIle.join(starting_directory,"**","*")].each do |entry|
    next unless FIle.ftype(entry) == "file"
    IO.foreach(entry) do |line|
      if line =~ str
        puts "#{filename}: #{line} "
        puts "--------------------------------------------------"
        # logger = Logger.new($stdout) # ← this is useless, you're not doing anything with this, and setting it each time through the loop is a waste
      end # if
    end # IO.foreach
  end # Dir..each
end

grep_r(%r{some|set|of|words|to|find}, '.')
grep_r(%r{someother|set|of|words to find},File.join(ENV['HOME'],'Documents',"ThatImportantProject"))

···

On Sep 13, 2013, at 11:30 AM, amanda honey <lists@ruby-forum.com> wrote:

I can get this to work but only in the directory that the script resides
in.
If i change the dir_path to a different directory it says that the file
its trying to read is a directory.
Any help would be welcome...

dir_path = '.'
str = /somearray|with|logts|of|strings/

# Searching for string
Dir.chdir(dir_path) do
Dir.glob("*") do |filename|
   IO.foreach(filename) do |line|
     if line =~ str
       puts "#{filename}: #{line} "
       puts "--------------------------------------------------"
       logger = Logger.new($stdout)
   end
end
end

--
Posted via http://www.ruby-forum.com/\.

Thanks guys!

Pathname.pwd.find do |f|
  next if f.directory?

  f.each_line.find {|line| strcpyArray =~ line and puts "#{f}: #{line}
" }

end

Worked perfectly for what I needed to do.
I am learning allot from this. It was easy to whip a script in bash to
do this but it really just takes too much resources using grep. This
works so much better. =-) I cant wait till I am not so green with Ruby
=-)

···

--
Posted via http://www.ruby-forum.com/.

Why did nobody recommend Find or Pathname?

require 'find'

rx = /somearray|with|logts|of|strings/

Find.find '.' do |f|
  next if File.directory? f

  File.foreach f do |line|
    if rx =~ line
      puts f
      break
    end
  end
end

# or

Find.find '.' do |f|
  next if File.directory? f

  File.foreach(f).find {|line| rx =~ line} and puts f
end

# or

require 'pathname'

Pathname.pwd.find do |f|
  next if f.directory?

  f.each_line
    if rx =~ line
      puts f
      break
    end
  end
end

# or

Pathname.pwd.find do |f|
  next if f.directory?

  f.each_line.find {|line| rx =~ line} and puts f
end

If file names are only to be displayed and not further processed in
the Ruby program there is a much simpler solution on the command
prompt of a reasonable OS:

find -type f -exec egrep -l 'somearray|with|logts|of|strings' {} +

Cheers

robert

···

On Sat, Sep 14, 2013 at 4:58 AM, Tamara Temple <tamouse.lists@gmail.com> wrote:

A simple enough rewrite:

def grep_r(search_criteria, starting_directory='.')
  raise "Search criteria must be a regular expression" unless search_criteria.kind_of? Regexp
  raise "Starting point not a directory" unless File.directory? starting_directory
  Dir[FIle.join(starting_directory,"**","*")].each do |entry|
    next unless FIle.ftype(entry) == "file"
    IO.foreach(entry) do |line|
      if line =~ str
        puts "#{filename}: #{line} "
        puts "--------------------------------------------------"
        # logger = Logger.new($stdout) # ← this is useless, you're not doing anything with this, and setting it each time through the loop is a waste
      end # if
    end # IO.foreach
  end # Dir..each
end

grep_r(%r{some|set|of|words|to|find}, '.')
grep_r(%r{someother|set|of|words to find},File.join(ENV['HOME'],'Documents',"ThatImportantProject"))

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

How did you do it in the shell that it took so much resources? Did
you try the variant I have posted earlier?

Kind regards

robert

···

On Fri, Sep 20, 2013 at 2:43 AM, amanda honey <lists@ruby-forum.com> wrote:

Thanks guys!

Pathname.pwd.find do |f|
  next if f.directory?

  f.each_line.find {|line| strcpyArray =~ line and puts "#{f}: #{line}
" }

end

Worked perfectly for what I needed to do.
I am learning allot from this. It was easy to whip a script in bash to
do this but it really just takes too much resources using grep. This
works so much better. =-) I cant wait till I am not so green with Ruby
=-)

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

A simple enough rewrite:

def grep_r(search_criteria, starting_directory='.')
raise "Search criteria must be a regular expression" unless search_criteria.kind_of? Regexp
raise "Starting point not a directory" unless File.directory? starting_directory
Dir[FIle.join(starting_directory,"**","*")].each do |entry|
   next unless FIle.ftype(entry) == "file"
   IO.foreach(entry) do |line|
     if line =~ str
       puts "#{filename}: #{line} "
       puts "--------------------------------------------------"
       # logger = Logger.new($stdout) # ← this is useless, you're not doing anything with this, and setting it each time through the loop is a waste
     end # if
   end # IO.foreach
end # Dir..each
end

grep_r(%r{some|set|of|words|to|find}, '.')
grep_r(%r{someother|set|of|words to find},File.join(ENV['HOME'],'Documents',"ThatImportantProject"))

Why did nobody recommend Find or Pathname?

WHY OH WHY???

cos

require 'find'

rx = /somearray|with|logts|of|strings/

Find.find '.' do |f|
next if File.directory? f

This will pass things other than files: pipes, sockets, etc

File.foreach f do |line|
   if rx =~ line
     puts f
     break
   end
end
end

# or

Find.find '.' do |f|
next if File.directory? f

File.foreach(f).find {|line| rx =~ line} and puts f
end

# or

require 'pathname'

Pathname.pwd.find do |f|
next if f.directory?

f.each_line
   if rx =~ line
     puts f
     break
   end
end
end

# or

Pathname.pwd.find do |f|
next if f.directory?

f.each_line.find {|line| rx =~ line} and puts f
end

If file names are only to be displayed and not further processed in
the Ruby program there is a much simpler solution on the command
prompt of a reasonable OS:

find -type f -exec egrep -l 'somearray|with|logts|of|strings' {} +

or

grep -rlE 'somearray|with|logts|of|strings' .

TMTOWTDT

···

On Sep 14, 2013, at 5:25 AM, Robert Klemme <shortcutter@googlemail.com> wrote:

On Sat, Sep 14, 2013 at 4:58 AM, Tamara Temple <tamouse.lists@gmail.com> wrote:

Cheers

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Why did nobody recommend Find or Pathname?

WHY OH WHY???

The horrors...

cos

require 'find'

rx = /somearray|with|logts|of|strings/

Find.find '.' do |f|
next if File.directory? f

This will pass things other than files: pipes, sockets, etc

That is easily fixed

Find.find '.' do |f|
  File.foreach(f).find {|line| rx =~ line} and puts f if File.file? f
end

If file names are only to be displayed and not further processed in
the Ruby program there is a much simpler solution on the command
prompt of a reasonable OS:

find -type f -exec egrep -l 'somearray|with|logts|of|strings' {} +

or

grep -rlE 'somearray|with|logts|of|strings' .

TMTOWTDT

Right! I'm so used to using find that I keep forgetting *grep's
option "-r". Thank you for the reminder!

Cheers

robert

···

On Sun, Sep 15, 2013 at 12:49 AM, Tamara Temple <tamouse.lists@gmail.com> wrote:

On Sep 14, 2013, at 5:25 AM, Robert Klemme <shortcutter@googlemail.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/