Как получить входящий поток в ruby ​​-e в командной строке?

Я пытаюсь понять, как написать один лайнер на консоли bash и pipe to ruby, но я не могу понять, как получить вход. Это не работает:

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

Как я могу получить входящий поток в ruby?

Ответ 1

Ruby рассматривает вашу строку как комментарий, потому что она начинается с #.

Это будет работать:

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

Вывод:

my string

Я использовал Kernel#gets вместо STDIN.gets:

Возвращает (и присваивает $_) следующую строку из списка файлов в ARGV (или $*) или со стандартного ввода, если в командной строке нет файлов

Если вы хотите обработать каждую строку, вы можете использовать флаг -p. Это как обернуть ваш script в блок while gets(); ... end; puts $_. Ruby считывает каждую строку ввода в $_, оценивает ваш script и выводит $_ после:

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

Вывод:

foo
bar
baz

Ответ 2

Просто

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

или

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

Вы получаете идею.

Ответ 3

Примеры:

Удалите все строки из дополнительных пробелов:

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

Случайно раскрашивать каждую строку:

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

Сортировка строк по длине:

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

Сортировка файлов по размеру файла:

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") }'

и т.д.. и др.