Я хочу иметь дело с вводом командной строки в Ruby:
> cat input.txt | myprog.rb
> myprog.rb < input.txt
> myprog.rb arg1 arg2 arg3 ...
Каков наилучший способ сделать это? В частности, я хочу иметь дело с пустым STDIN и надеюсь на элегантное решение.
#!/usr/bin/env ruby
STDIN.read.split("\n").each do |a|
puts a
end
ARGV.each do |b|
puts b
end
myprog.rb
:input.txt
файл прикреплен к stdin ; оболочка управляет этим для вас.Ответы:
Ниже приведены некоторые вещи, которые я нашел в своей коллекции малоизвестного Ruby.
Итак, в Ruby простая реализация команды Unix без звонков
cat
будет выглядеть так:ARGF
Ваш друг, когда дело доходит до ввода; это виртуальный файл, который получает все входные данные из именованных файлов или все из STDIN.Слава Богу, мы не получили алмазного оператора в Ruby, но мы получили
ARGF
в качестве замены. Хотя неясно, на самом деле это оказывается полезным. Рассмотрим эту программу, которая добавляет заголовки авторских прав на место (благодаря другому Perlism-i
) к каждому файлу, указанному в командной строке:Кредит для:
источник
idx
это будет «номер строки» в виртуальном файле, объединяющий все входы, а не номер строки для каждого отдельного файла.#!/usr/bin/env ruby -i
строка не работает в Linux: stackoverflow.com/q/4303128/735926Ruby предоставляет другой способ обработки STDIN: флаг -n. Он рассматривает всю вашу программу как внутри цикла по STDIN (включая файлы, передаваемые как аргументы командной строки). Смотрите, например, следующий 1-строчный скрипт:
источник
#!/usr/bin/env ruby -n
не будет работать, так как «ruby -n» будет передан / usr / bin / env в качестве единственного аргумента. Смотрите этот ответ для более подробной информации. Скрипт будет работать, если запустить егоruby -n script.rb
явно.Я не совсем уверен, что вам нужно, но я бы использовал что-то вроде этого:
Обратите внимание, что поскольку массив ARGV пуст перед первым
gets
, Ruby не будет пытаться интерпретировать аргумент как текстовый файл для чтения (поведение, унаследованное от Perl).Если стандартный ввод пуст или аргументов нет, ничего не печатается.
Несколько тестовых случаев:
источник
Может быть, что-то подобное?
Пример:
источник
Это вдохновлено Perl:
источник
Быстро и просто:
STDIN.gets.chomp == 'YES'
источник
Я добавлю это, чтобы использовать
ARGF
с параметрами, вам нужно очиститьARGV
перед вызовомARGF.each
. Это потому, чтоARGF
будет обрабатывать что-либоARGV
как имя файла и сначала читать строки оттуда.Вот пример реализации 'tee':
источник
Я делаю что-то вроде этого:
источник
Кажется, что большинство ответов предполагают, что аргументы являются именами файлов, содержащими контент, который нужно передать на стандартный ввод. Ниже все трактуется как аргументы. Если STDIN из TTY, то он игнорируется.
Либо аргументы, либо stdin могут быть пустыми или иметь данные.
источник