LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   need help with a ruby script listing directory contents (http://www.linuxquestions.org/questions/programming-9/need-help-with-a-ruby-script-listing-directory-contents-515077/)

Joseph Schiller 12-31-2006 01:00 AM

need help with a ruby script listing directory contents
 
Hi,

When browsing sources of any software distribution, usually I find hundreds or thousands of files across different directories, but hardly ever an inventory file. If I want to browse files of one type, it is all too easy to break out advanced tools like grep and search through each one, even down to a particular string within a file, using a one-liner as in

gvim `grep -l query_word *.java` and then page through the buffers in vim using :bn

but I find that cumbersome in a large distribution. Imagine searching for 'socket' you could have a hundred "hits". Using ls -R | less will produce all the files and subdirectories which I don't want. I want to tailor a script to produce a listing of files and subdirectories that match a particular type like .java or .h source files. I came up with a sort of solution, but if doesn't meet the requirements if you launch it at the top of the directory tree.

Code:

#!/bin/ruby
# dirlist.rb
require 'find'
puts "please enter a directory to search: "
directory = gets.chomp
puts "please enter file type: "
filetype = "." + gets.chomp
puts

Find.find(directory) do |filename|
    if (filename != "." && filename != "..")
    then
        filename.each do |f|
            next unless f =~ (/#{filetype}/)
              puts f
        end
    end
end

It doesn't work with redirection to a file because of the prompting, and I don't know ahead of time all the file types that I may want to search through next week or next month, so adding complex search logic is moot.
How can I improve it to list only .txt or .java source files inside subdirectories?

Similar solution works but only inside one directory:

Code:

Dir.open(directory) do |dir|
    if (dir != "." && dir != "..")
        then
            dir.each do |file|
              next unless file =~ (/#{filetype}/)
                  puts file
            end
    end
end

(Please accept my apologies for the lack of indentation)

With kindest regards,

joe

jschiwal 12-31-2006 01:20 AM

Use the [ code ]...[ / code ] markup to add the indentation. I filter long searches with grep by eliminating what I don't need:
locate .java | grep -v -e <term1> -e <term2>

I'll type the output of locate through grep in this way, hit the up arrow, and keep adding -e arguments. The -v option is to eliminate matches.

Sorry, I haven't learned ruby yet. I prefer scripts that take arguments instead of prompting for input. For general searches based on the contents of a file, I tend to use beagle. I use beagle search almost as often as I use Google for web searches. Maybe this is because I'm a bit of a pack rat when it comes to documents I find on the web, or generate from package sources.

makyo 12-31-2006 06:55 AM

Hi.

I use glimpse and glimpseindex to index specific directories. In the Debian world, the glimpse tools are easily available from the repository.

I have the indexer run at night, then the search is good until I add a number of files. Re-indexing is quite fast, and if you wish to limit the search you can:
Code:

For
      example,

      glimpse -F '\.c$' needle

      will  find  the  pattern  needle  in all files whose name ends with .c.

-- man glimpse

I find this easier than building one's own tool (but possibly less satisfying). An interesting form of grep -- agrep, approximate grep -- often comes with glimpse ... cheers, makyo

Joseph Schiller 12-31-2006 07:54 AM

Thanks for the tip. glimpse however is not featured in my distro, and indexing entire filesystem has its merits. Using locate and find utilities would also suffice. But the task at hand is miniscule not worthy even of grep. If you ever chanced upon the java sources from the hallmarks of apache.org, there are thousands of fine files to stay awake for. Great reading, too. Until you start peeking inside directories and interdependencies, you'll soon become lost in a maze.

Prompting and redirecting output can coexist together but from inside the script.

Code:

#!/bin/ruby
# dirlist.rb
require 'find'
puts "please enter directory to search: "
directory = gets.chomp
puts "please enter filetype to search: "
filetype = "." + gets.chomp
puts
outfile = File.open("out.txt", "w") # will be overwritten each run
Find.find(directory) do |filename|
    filename.each do |f|
        next unless f =~ (/#{filetype}/)
            outfile.write(f+"\n")  # need a newline here
    end
end
outfile.close

The pattern matching =~ needs work though. On my machine a query for 'java' returns also javadocs.xml, but sure beats locate and find which in addition to the requested directory also dip into the home directory (not sure why).

Kindest regards,

joe

jschiwal 12-31-2006 11:46 PM

You might also want to look into ctags to generate an index of your source, if your language is supported.

Also, doxygen is used to generate documentation from source.


All times are GMT -5. The time now is 10:48 PM.