Found a neat trick for doing recursive one-liners

P

Pat Maddox

Or you can use the tools designed for finding stuff :)

find . -name "*.txt" | xargs grep Hello

That version will work for all files. You can play with find to match
any file you want.

Pat
 
A

ara.t.howard

This is probably something everyone in here already knows about, but I
thought it was cool enough that I wanted to post about it.

If you want to create a one liner to say search all the *.txt files
in and under the current directory for text matching "Hello", you can do
this

find -name '*.txt' -exec ruby -ne 'print if /Hello/' '{}' ';'

I know you can do this in pure ruby in like 3 lines if you use the Find
module, but I really wanted to do it with a one liner. Earlier I tried
something like this

ruby -ne 'print if /Hello/' `find -name '*.txt'`

ruby -e' puts Dir["**/**"].select{|e| e =~ /a.rb/} '

-a
--
===============================================================================
| ara [dot] t [dot] howard [at] noaa [dot] gov
| all happiness comes from the desire for others to be happy. all misery
| comes from the desire for oneself to be happy.
| -- bodhicaryavatara
===============================================================================
 
G

Gary Watson

This is probably something everyone in here already knows about, but I
thought it was cool enough that I wanted to post about it.

If you want to create a one liner to say search all the *.txt files
in and under the current directory for text matching "Hello", you can do
this

find -name '*.txt' -exec ruby -ne 'print if /Hello/' '{}' ';'

I know you can do this in pure ruby in like 3 lines if you use the Find
module, but I really wanted to do it with a one liner. Earlier I tried
something like this

ruby -ne 'print if /Hello/' `find -name '*.txt'`

unfortunately that version would fail if there were any spaces in the
filenames.
 
N

nobuyoshi nakada

Hi,

At Tue, 27 Dec 2005 12:57:53 +0900,
Gary Watson wrote in [ruby-talk:172611]:
I know you can do this in pure ruby in like 3 lines if you use the Find
module, but I really wanted to do it with a one liner. Earlier I tried
something like this

ruby -ne 'print if /Hello/' `find -name '*.txt'`

unfortunately that version would fail if there were any spaces in the
filenames.

ruby -ne 'BEGIN{ARGV.replace(Dir[ARGV.join("\0")])}; print if /Hello/' '**/*.txt'
 
G

Gary Watson

I apologize for using a brain dead example. I was more excited about the
prospect of hitting all files under the current directory recursively, not
the actual processing I used in my examples. Thanks for the pointer to
xargs. I didn't know about that one, I'll have to take a closer look at
it's man page.
 
X

x1

Ara, I always love your examples! :) Please keep contributing to the
community!!

BTW, I have the process management class working like a champ.. I'll
share the code with you later!



This is probably something everyone in here already knows about, but I
thought it was cool enough that I wanted to post about it.

If you want to create a one liner to say search all the *.txt files
in and under the current directory for text matching "Hello", you can d= o
this

find -name '*.txt' -exec ruby -ne 'print if /Hello/' '{}' ';'

I know you can do this in pure ruby in like 3 lines if you use the Find
module, but I really wanted to do it with a one liner. Earlier I tried
something like this

ruby -ne 'print if /Hello/' `find -name '*.txt'`

ruby -e' puts Dir["**/**"].select{|e| e =3D~ /a.rb/} '

-a
--
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
| ara [dot] t [dot] howard [at] noaa [dot] gov
| all happiness comes from the desire for others to be happy. all misery
| comes from the desire for oneself to be happy.
| -- bodhicaryavatara
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
 
G

Gary Allum

I know Im a n00b, but I think more than anything, its good to see you so =
=20
excited about Ruby. Learning new things really is fun in Ruby.

I apologize for using a brain dead example. I was more excited about t= he
prospect of hitting all files under the current directory recursively, = =20
not
the actual processing I used in my examples. Thanks for the pointer to
xargs. I didn't know about that one, I'll have to take a closer look a= t
it's man page.



--=20
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
 
J

James Britt

Pat said:
Or you can use the tools designed for finding stuff :)

find . -name "*.txt" | xargs grep Hello

That version will work for all files. You can play with find to match
any file you want.

Assuming you are on a machine with find, xargs, and grep, as opposed to
just Ruby.

I like the idea of assembling command line utils that will work on any
platform where Ruby is installed (e.g., all the machines in my house).

I also like the idea of reinventing the wheel in Ruby because sometimes
you get a better wheel. Or at least one that is more hackable.

James

--

http://www.ruby-doc.org - Ruby Help & Documentation
http://www.artima.com/rubycs/ - Ruby Code & Style: Writers wanted
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
http://www.30secondrule.com - Building Better Tools
 
P

Philip Rhoades

Ara,


This is probably something everyone in here already knows about, but I
thought it was cool enough that I wanted to post about it.

If you want to create a one liner to say search all the *.txt files
in and under the current directory for text matching "Hello", you can do
this

find -name '*.txt' -exec ruby -ne 'print if /Hello/' '{}' ';'

I know you can do this in pure ruby in like 3 lines if you use the Find
module, but I really wanted to do it with a one liner. Earlier I tried
something like this

ruby -ne 'print if /Hello/' `find -name '*.txt'`

ruby -e' puts Dir["**/**"].select{|e| e =~ /a.rb/} '


That doesn't seem to do anything . .

Phil.
--
Philip Rhoades

Pricom Pty Limited (ACN 003 252 275 ABN 91 003 252 275)
GPO Box 3411
Sydney NSW 2001
Australia
Mobile: +61:(0)411-185-652
Fax: +61:(0)2-8221-9599
E-mail: (e-mail address removed)
 
D

dblack

Hi --

This is probably something everyone in here already knows about, but I
thought it was cool enough that I wanted to post about it.

If you want to create a one liner to say search all the *.txt files
in and under the current directory for text matching "Hello", you can do
this

find -name '*.txt' -exec ruby -ne 'print if /Hello/' '{}' ';'

I know you can do this in pure ruby in like 3 lines if you use the Find
module, but I really wanted to do it with a one liner. Earlier I tried
something like this

ruby -ne 'print if /Hello/' `find -name '*.txt'`

ruby -e' puts Dir["**/**"].select{|e| e =~ /a.rb/} '

We've strayed a little from the original thing, but along those lines
you could also do:

ruby -e 'puts Dir["**/**"].grep(/a\.rb/)'

(just guessing about the \. part :)

or maybe even:

ruby -e 'puts Dir["**/*a.rb*/"]


David

--
David A. Black
(e-mail address removed)

"Ruby for Rails", from Manning Publications, coming April 2006!
http://www.manning.com/books/black
 
M

Michael Fellinger

--nextPart12089810.X6MrFAzrSh
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

I really prefer the simple variant...
ruby -e 'puts Dir["**/a*.{rb}"]'

finds all .rb that start with 'a', recursive of course :)

Am Dienstag, 27. Dezember 2005 11:36 schrieb (e-mail address removed):
Hi --

This is probably something everyone in here already knows about, but I
thought it was cool enough that I wanted to post about it.

If you want to create a one liner to say search all the *.txt files
in and under the current directory for text matching "Hello", you can do
this

find -name '*.txt' -exec ruby -ne 'print if /Hello/' '{}' ';'

I know you can do this in pure ruby in like 3 lines if you use the Find
module, but I really wanted to do it with a one liner. Earlier I tried
something like this

ruby -ne 'print if /Hello/' `find -name '*.txt'`

ruby -e' puts Dir["**/**"].select{|e| e =~ /a.rb/} '

We've strayed a little from the original thing, but along those lines
you could also do:

ruby -e 'puts Dir["**/**"].grep(/a\.rb/)'

(just guessing about the \. part :)

or maybe even:

ruby -e 'puts Dir["**/*a.rb*/"]


David

--nextPart12089810.X6MrFAzrSh
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQBDsRtjMdQeL6eBxhIRAlxWAKCjMUik1zE8WQH5+1slioMiev476wCgjwOs
TGNLTzacXvaV6PDJEg8XTbI=
=nNiR
-----END PGP SIGNATURE-----

--nextPart12089810.X6MrFAzrSh--
 
R

Reinder Verlinde

Pat Maddox said:
Or you can use the tools designed for finding stuff :)

find . -name "*.txt" | xargs grep Hello

That version will work for all files.

<educational type="but not ruby related">
Not quite. For better (maximum?) robustness, pass '-print0' to find and
'-0' to xargs. That will handle filenames with spaces and/or quotes
correctly. (If your filenames have bytes with binary value zero in them,
you still will be out of luck)
</educational>

Reinder
 
S

Stefan Walk

Pat said:
Or you can use the tools designed for finding stuff :)

find . -name "*.txt" | xargs grep Hello

That version will work for all files. You can play with find to match
any file you want.

Pat

et@adel:/tmp/rb$ touch 'foo bar.txt'
et@adel:/tmp/rb$ find . -name "*.txt"
../foo bar.txt
et@adel:/tmp/rb$ find . -name "*.txt" | xargs grep Hello
grep: ./foo: No such file or directory
grep: bar.txt: No such file or directory
et@adel:/tmp/rb$ find . -name "*.txt" -print0 | xargs -0 grep Hello
et@adel:/tmp/rb$

Watch out if you are using xargs. It can get pretty nasty, especially if
there is not grep at work, but rm or alike.

Shooting yourself in the foot 101:
$ touch "foo .. bar -rf moo.o"
$ find . -name '*.o' | xargs rm
*BAM*

If you are using find and xargs, always use -print0 and -0, respectively.

Regards,
Stefan
 
W

W.B.Hill

Or you can use the tools designed for finding stuff :)

find . -name "*.txt" | xargs grep Hello

That version will work for all files. You can play with find to match
any file you want.

find . -regex '.*\.txt' -print0 | xargs -0 -n1000 grep Hello

-print0 and -0 to avoid trouble with spaces and other metagubbins.
-n1000 for a bit of a speedup
-regex to show you can ;-)
 
W

W.B.Hill

Know an OS where that is allowed?

NT 4 kernel mode API is quite happy with \0 in filenames. But it *really*
confuses the Win32 layer! Haven't played with later versions...
 
A

ara.t.howard

ruby -e' puts Dir["**/**"].select{|e| e =~ /a.rb/} '


That doesn't seem to do anything . .

then you probably don't have any files named 'a.rb' under the current
directory - i seem to have several hundred ;-)

cheers.

-a
--
===============================================================================
| ara [dot] t [dot] howard [at] noaa [dot] gov
| all happiness comes from the desire for others to be happy. all misery
| comes from the desire for oneself to be happy.
| -- bodhicaryavatara
===============================================================================
 
A

ara.t.howard

Hi --

ruby -e' puts Dir["**/**"].select{|e| e =~ /a.rb/} '


That doesn't seem to do anything . .

then you probably don't have any files named 'a.rb' under the current
directory - i seem to have several hundred ;-)

Or abrb, or acrb, or airbag, or.... :)

indeed. or diectories. that's the nice thing about using select:

ruby -e' puts Dir["**/**"].select{|e| test ?f, e and e =~ /^a\.rb$/} '

-a
--
===============================================================================
| ara [dot] t [dot] howard [at] noaa [dot] gov
| all happiness comes from the desire for others to be happy. all misery
| comes from the desire for oneself to be happy.
| -- bodhicaryavatara
===============================================================================
 
D

dblack

Hi --

On Tue, 27 Dec 2005, Philip Rhoades wrote:

ruby -e' puts Dir["**/**"].select{|e| e =~ /a.rb/} '


That doesn't seem to do anything . .

then you probably don't have any files named 'a.rb' under the current
directory - i seem to have several hundred ;-)

Or abrb, or acrb, or airbag, or.... :)

indeed. or diectories. that's the nice thing about using select:

ruby -e' puts Dir["**/**"].select{|e| test ?f, e and e =~ /^a\.rb$/} '

I was just obliquely pointing out the lack of ^ and \. and $ :) But
it's true that Dir.[] is not very seletcive.... In fact, I think I
once submitted an RCR to let it take a second argument that would be
tested for (like: Dir["**/**"],?f]) but it was rejected. So here I am
several years later still acting as if Dir.[] could read my mind....


David

--
David A. Black
(e-mail address removed)

"Ruby for Rails", from Manning Publications, coming April 2006!
http://www.manning.com/books/black
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top