Ich möchte mich mit der Befehlszeileneingabe in Ruby befassen:
> cat input.txt | myprog.rb
> myprog.rb < input.txt
> myprog.rb arg1 arg2 arg3 ...
Was ist der beste Weg, um es zu tun? Insbesondere möchte ich mich mit leerem STDIN befassen und hoffe auf eine elegante Lösung.
#!/usr/bin/env ruby
STDIN.read.split("\n").each do |a|
puts a
end
ARGV.each do |b|
puts b
end
myprog.rb
: Dieinput.txt
Datei wird an stdin angehängt ; Die Shell verwaltet dies für Sie.Antworten:
Im Folgenden sind einige Dinge aufgeführt, die ich in meiner Sammlung von obskurem Ruby gefunden habe.
In Ruby wäre eine einfache No-Bells-Implementierung des Unix-Befehls
cat
also:ARGF
ist dein Freund, wenn es um Input geht; Es ist eine virtuelle Datei, die alle Eingaben von benannten Dateien oder alle von STDIN erhält.Gott sei Dank haben wir den Diamantenbetreiber in Ruby nicht bekommen, aber wir haben ihn
ARGF
als Ersatz bekommen. Obwohl dunkel, erweist es sich tatsächlich als nützlich. Betrachten Sie dieses Programm, bei dem Copyright-Header (dank eines anderen Perlismus-i
) jeder in der Befehlszeile genannten Datei vorangestellt werden:Gutschrift an:
quelle
idx
dies die "Zeilennummer" in der virtuellen Datei ist, die alle Eingaben verkettet, und nicht die Zeilennummer für jede einzelne Datei.#!/usr/bin/env ruby -i
Zeile unter Linux nicht funktioniert: stackoverflow.com/q/4303128/735926Ruby bietet eine andere Möglichkeit, mit STDIN umzugehen: Das Flag -n. Es behandelt Ihr gesamtes Programm als eine Schleife über STDIN (einschließlich Dateien, die als Befehlszeilenargumente übergeben werden). Siehe zB das folgende 1-zeilige Skript:
quelle
#!/usr/bin/env ruby -n
funktioniert nicht, da "ruby -n" als einziges Argument an / usr / bin / env übergeben wird. Siehe diese Antwort für weitere Details. Das Skript wird funktionieren , wenn mit laufenruby -n script.rb
explizit.Ich bin mir nicht ganz sicher, was Sie brauchen, aber ich würde so etwas verwenden:
Beachten Sie, dass
gets
Ruby , da das ARGV-Array zuvor leer war , nicht versucht, das Argument als Textdatei zu interpretieren, aus der gelesen werden soll (von Perl geerbtes Verhalten).Wenn stdin leer ist oder keine Argumente vorhanden sind, wird nichts gedruckt.
Einige Testfälle:
quelle
So etwas vielleicht?
Beispiel:
quelle
Dies ist inspiriert von Perl:
quelle
Schnell und einfach:
STDIN.gets.chomp == 'YES'
quelle
Ich werde das hinzufügen, um
ARGF
mit Parametern zu verwenden, müssen SieARGV
vor dem Aufruf löschenARGF.each
. Dies liegt daranARGF
, dass alles inARGV
als Dateiname behandelt wird und zuerst die Zeilen von dort gelesen werden.Hier ist ein Beispiel für eine Tee-Implementierung:
quelle
Ich mache so etwas:
quelle
Es scheint, dass die meisten Antworten davon ausgehen, dass die Argumente Dateinamen sind, die Inhalte enthalten, die dem Standard zugeordnet werden sollen. Im Folgenden wird alles nur als Argument behandelt. Wenn STDIN vom TTY stammt, wird es ignoriert.
Entweder Argumente oder stdin können leer sein oder Daten enthalten.
quelle