Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get piped input to ruby -e on command line?

I'm trying to figure out how to write one liners on the bash console and pipe to ruby but I can't figure out how to get the input. This isn't working:

echo "My String" | ruby -e "#{STDIN.read.first.downcase}"

How can I get the piped input in ruby?

like image 488
pixelearth Avatar asked Jun 13 '13 20:06

pixelearth


3 Answers

Ruby treats your line as a comment because it starts with a #.

This would work:

echo "My String" | ruby -e "puts gets.downcase"

Output:

my string

I've used Kernel#gets instead of STDIN.gets:

Returns (and assigns to $_) the next line from the list of files in ARGV (or $*), or from standard input if no files are present on the command line

If you want to process each line, you could use the -p flag. It's like wrapping your script in a while gets(); ... end; puts $_ block. Ruby reads each input line into $_, evaluates your script and outputs $_ afterwards:

echo "Foo\nBar\nBaz" | ruby -pe '$_.downcase!'

Output:

foo
bar
baz
like image 61
Stefan Avatar answered Nov 08 '22 19:11

Stefan


Examples:

Strip all lines from extra spaces:

ls | ruby -e "STDIN.each_line.to_a.map(&:strip).each(&method(:puts))"

Randomly colorize each line:

ls | ruby -e "require 'colorize'; STDIN.each_line { |l| print l.colorize(String.colors.sample) }"

Sort lines by length:

ls | ruby -e "puts STDIN.each_line.to_a.sort_by(&:size).reverse"

Sort files by file size:

ls -l | ruby -e 'STDIN.first; puts STDIN.each_line.to_a.map { |l| [l.split[4].to_i, l.split[8]] }.sort_by(&:first).reverse.map { |l| l.join("\t") }'

etc. etc.

like image 30
Dorian Avatar answered Nov 08 '22 20:11

Dorian


Just

echo "My String" | ruby -ne 'puts $_.downcase'

or

echo "My String" | ruby -e "puts gets.downcase"

You get the idea.

like image 7
Jerome Dalbert Avatar answered Nov 08 '22 18:11

Jerome Dalbert