Hey. I started having enough of typing find ./ -name *.ext |xargs grep "a string that interests me", so i decided to create a wrapper. My initial thought was to do it in perl, but since i've left my camel book many kilometers away at my parents' house, and got accustomed to the GUILE Scheme, i eventually used GUILE. The idea was to write in bash

Code

search for "a string that interests me" \ or "some other string" in *.ext or *.txt

I have been wondering, though, how would it be best to write such script in perl. Intuitively, perl seems the perfect language for that application, but to tell the truth, i wouldn't even know how to start... (the problem is the possible set of "or" expressions, which were handled moderately elegantly using pattern matching and recursion in Scheme)

You can certainly use Perl to emulate the find command, and it should be fairly easy. Probably far less code lines than your Scheme implementation, but I don't understand Scheme well enough to understand in detail what you are doing in your script.

where @for and @in are arrays obtained from processing appropriate clauses. The only problem that i have is with processing those clauses. It would be perfect if the source code was similar to what i wrote here, because i think it's the best way to explain what i mean.

Well, the whole idea is to be able to type the following(or any variation of the allowed grammar) on the command line:

Code

$ search for "a string that interests me" \ or "some other string" in *.ext or *.txt

...and have the program do what the English says. The op's second post complicates things even further by expanding on the allowed grammar. Writing a new program for every search is not what the op is after.

Yes, I'd find that rather odd, indeed :] I decided to write a wrapper on UNIX commands find, xargs and grep, because I frequently write in the command line:

Code

$ find ./ -name '*.txt' | xargs grep regexp

and I recently concluded that it's a lot of typing, and that I could write a simple bash or perl script instead, that would invoke all those commands for me. I wanted to have a tool that would be natural to use, especially for frequent cases. I decided to give the possibility to provide an easy 'or' option, because this logical operation is done differently in find, and differently in grep, and I don't want to check the manual all over again. I also wanted the source to be easy -- to rather contain description of the grammar instead of explicit iteration. I achieved that easily in Scheme, because the language provides a natural structure pattern matcher. (The solution wasn't perfect, but I think it's tollerably elegant). Although there is a structure pattern matcher for PERL available in CPAN (right here: http://search.cpan.org/~kstephens/Data-Match-0.06/Match.pm), I find it very idiosyncratic and expect that it might have too limited capabilities.

Anyway, since the task was so simple, I thought that there should be a straightforward way to accomplish it in PERL. And as for now, I'm a little surprised.

Well, actually parsing the command line is the key theme here -- whether I invoke GNU find, or implement my own find in perl, is not that important, and it makes no difference except that the former is shorter and probably less portable.

Besides, of course I could use Getopt::Long as you suggest, but again -- that's not what I want. I don't want to have to precede my preopositions with '--', because I find it redundant and uncomfortable. I'm looking for the best solution to the problem that I described, not for a description of a similar problem that would be easier to solve (although I do appreciate your suggestion). Or, to put it more generally, I don't want to bend myself to the limitations of particular computer systems, but I prefer to bend the computer systems to my will.

1) Using a grammar parser is a common way to solve problems like yours. I've been working on a solution using perl's Parse::RecDescent parser, but I find it very difficult to use, and the solution feels brittle. I've used python's PyParsing recursive descent parser, and it is much easier to use and the solutions feel more robust.

2) I think you have problems with your grammar because the bash shell drops the quotes around the strings that you want to specify as search terms, so any program will be handed a jumble of words for the search strings with no way to separate them. You can escape the quotes on the command line but that will make it very unwieldy to type the command.

In addition, I don't know if your Scheme program handles it or not, but the shell expands globs(file patterns), so if you use: '*.pl or *.txt' in your command, the shell is going to feed your program something similar to this:

prog1.pl prog2.pl or data1.txt data2.txt

Unfortunately, I'm finding that to be problematic because perl's Parse::RecDescent doesn't back up like a regex engine. So if you try to match 'or' followed by several words, the perl parser will gladly gobble up all the remaining words in the command string and terminate.

You have already 'considered' my suggestion. I cannot ask for more. In lieu of that, 7Stud is probably on the right track. It would be ideal if you can find a parsing module which accepts the syntax specification in the meta-language you used in your second post. Time spent searching CPAN is seldom wasted even if you fail to find exactly what you want. Good Luck, Bill