Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Neither Python nor Ruby are best suited for one-liners that the author is emphasising. One liners are bash-fu or commandline-fu. Anything above 100 lines (just a figure from the article) is what Python or Ruby should be used for.

Last 10 lines in a file? 'tail -10 filename.txt'

Right tools for the right job.

As to Python vs Ruby? I believe the argument isn't about the language (although I think Python is more 'sane' :) ), but the community that surrounds it. And I like the Python community.



     Last 10 lines in a file? 'tail -10 filename.txt'
A lot uglier, but you can do a one liner ...

     ruby -e 'lines=[]; while gets(); lines << $_; \
       lines = lines[-10,10] unless $. < 10; end; \
       puts lines' < filename.txt
The problem with using "the right tool for the right job" is that there are many tools and many jobs, and a general purpose language helps you get things done in case you're stuck. In general I use Ruby for doing string manipulation before piping to other commands.

Here's an (ugly) one liner that shows the biggest tables in a MySQL database:

     mysql -u root godzilla -s -e 'show tables' \
     | ruby -ne '$_.strip!; puts %Q{SELECT count(*) \
       as cnt, "#$_" as tbl FROM #$_; }' \
     | mysql -u root godzilla -s \
     | sort -nr \
     | ruby -ne 'parts = $_.split /\s+/; \
       puts "%40s : %s" % parts.reverse' \
     | head -10
You can probably come up with something more clever, but I barely gave that one any thought.


> A lot uglier, but you can do a one liner ...

Yeah, but that one-liner reads the whole file. 'tail' can be more clever (and is). 'strace' output:

    open("a", O_RDONLY)                     = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=545975512, ...}) = 0
    lseek(3, 0, SEEK_CUR)                   = 0
    lseek(3, 0, SEEK_END)                   = 545975512
    lseek(3, 545972224, SEEK_SET)           = 545972224
    read(3, "tu 11.04 \\n \\l\n\nUbuntu 11.04 \\n "...,     3288) = 3288
'tail' is seeking to the end, then reading backwards.

The point being, these 'little tools' can contain important optimisations - they aren't necessarily equivalent to a naive reimplementation.


Reminds me on that article on GNU grep doing some speedy magic: http://lists.freebsd.org/pipermail/freebsd-current/2010-Augu...


tail can be done in ruby can be quite succinctly with the $< (ARGF) variable:

  ruby -e'$><<$<.map.last(10)'
For the rest of the ruby one-liners in the page the author references, most can be done more easily with standard command line tools (although most people aren't well-versed in sed, so 'ruby -pe puts' might be better than 'sed G').


There's one big problem with code like that. If you're doing devops-y stuff, then you really, really don't want to debug something like that when your pager goes off at 3am. The cleaner the solution the better, because after you wake up `$><<$<` is just a blurred thing with no meaning...


Cool. That hurts my eyes.

    ruby -e "print ARGF.readlines.last(10)"


on, say, a 5GB log file?..

If I read this correctly (http://www.ruby-doc.org/core/classes/IO.html#M000914) it'll read the whole file into an array, then spit out last 10 entries?


Yes it does - good point, but the sigil-tastic snippet in the parent reads the whole file into an array, too - it's just harder to tell.

Plus the parent snippet is not Ruby 1.9 compatible.

Anyways, my version was just to illustrate that sysadmin scripting in Ruby does not have illegible.


Not that you can't do this in python:

python -c "print '\n'.join(open('LICENSE.txt','r').read().split('\n')[:-10])"

But this is besides the point.


Your split and join seem redundnant, and open defaults to read-only.

  print open('whatever.file').readlines()[:-10]
But still, don't do that on any log too big to read into memory.


tac filename.txt | sed 10q | tac




Consider applying for YC's Winter 2027 batch! Applications are open till November 2.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: