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

Try using Dir[’**/.’]

On Sat, Sep 14, 2013 at 4:58 AM, Tamara T. [email protected]
wrote:

    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?

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 Sep 13, 2013, at 11:30 AM, amanda honey [email protected] wrote:

Searching for string


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 Sun, Sep 15, 2013 at 12:49 AM, Tamara T.
[email protected] wrote:

On Sep 14, 2013, at 5:25 AM, Robert K. [email protected] wrote:

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

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

Cheers

robert

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
=-)

On Sep 14, 2013, at 5:25 AM, Robert K. [email protected]
wrote:

 if line =~ str

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

Pathname.pwd.find do |f|

or

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 Fri, Sep 20, 2013 at 2:43 AM, amanda honey [email protected]
wrote:

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
=-)

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