Eu quero lidar com a entrada da linha de comando no Ruby:
> cat input.txt | myprog.rb
> myprog.rb < input.txt
> myprog.rb arg1 arg2 arg3 ...
Qual é a melhor maneira de fazer isso? Em particular, quero lidar com o STDIN em branco e espero uma solução elegante.
#!/usr/bin/env ruby
STDIN.read.split("\n").each do |a|
puts a
end
ARGV.each do |b|
puts b
end
myprog.rb
: oinput.txt
arquivo é anexado ao stdin ; o shell gerencia isso para você.Respostas:
A seguir, algumas coisas que encontrei em minha coleção de Ruby obscuros.
Portanto, no Ruby, uma implementação simples e sem sinos do comando Unix
cat
seria:ARGF
é seu amigo quando se trata de entrada; é um arquivo virtual que obtém toda a entrada de arquivos nomeados ou de STDIN.Graças a Deus não conseguimos o operador de diamantes em Ruby, mas conseguimos
ARGF
como um substituto. Embora obscuro, ele acaba sendo útil. Considere este programa, que anexa os cabeçalhos de direitos autorais no local (graças a outro perlismo-i
) a todos os arquivos mencionados na linha de comando:Crédito para:
fonte
idx
será o "número da linha" no arquivo virtual concatenando todas as entradas, em vez do número da linha de cada arquivo individual.#!/usr/bin/env ruby -i
linha não funciona em Linux: stackoverflow.com/q/4303128/735926Ruby fornece outra maneira de lidar com STDIN: o sinalizador -n. Ele trata todo o seu programa como estando dentro de um loop sobre STDIN (incluindo arquivos passados como argumentos de linha de comando). Veja, por exemplo, o seguinte script de 1 linha:
fonte
#!/usr/bin/env ruby -n
não funcionará, pois "ruby -n" será passado para / usr / bin / env como o único argumento. Veja esta resposta para mais detalhes. O script irá funcionar se correr comruby -n script.rb
explicitamente.Não tenho certeza do que você precisa, mas usaria algo como isto:
Observe que, como o array ARGV está vazio antes do primeiro
gets
, Ruby não tentará interpretar o argumento como um arquivo de texto para leitura (comportamento herdado do Perl).Se stdin estiver vazio ou não houver argumentos, nada será impresso.
Poucos casos de teste:
fonte
Algo assim talvez?
Exemplo:
fonte
Isso é inspirado no Perl:
fonte
Rápido e simples:
STDIN.gets.chomp == 'YES'
fonte
Acrescentarei que, para usar
ARGF
com os parâmetros, você precisa limparARGV
antes de ligarARGF.each
. Isso ocorre porqueARGF
tratará qualquer coisa emARGV
como um nome de arquivo e lerá as linhas a partir daí primeiro.Aqui está um exemplo de implementação 'tee':
fonte
Eu faço algo assim:
fonte
Parece que a maioria das respostas está assumindo que os argumentos são nomes de arquivos que contêm conteúdo a ser atribuído ao stdin. Abaixo de tudo é tratado como apenas argumentos. Se STDIN for do TTY, ele será ignorado.
Argumentos ou stdin podem estar vazios ou ter dados.
fonte