Je veux traiter l'entrée de ligne de commande dans Ruby:
> cat input.txt | myprog.rb
> myprog.rb < input.txt
> myprog.rb arg1 arg2 arg3 ...
Quelle est la meilleure façon de procéder? En particulier, je veux traiter du STDIN vierge et j'espère une solution élégante.
#!/usr/bin/env ruby
STDIN.read.split("\n").each do |a|
puts a
end
ARGV.each do |b|
puts b
end
myprog.rb
: leinput.txt
fichier est attaché à stdin ; le shell gère cela pour vous.Réponses:
Voici quelques choses que j'ai trouvées dans ma collection de Ruby obscure.
Ainsi, dans Ruby, une implémentation simple et sans cloches de la commande Unix
cat
serait:ARGF
est votre ami en matière de saisie; c'est un fichier virtuel qui obtient toutes les entrées des fichiers nommés ou toutes de STDIN.Dieu merci, nous n'avons pas obtenu l'exploitant de diamants à Ruby, mais nous l'avons obtenu
ARGF
en remplacement. Bien qu'obscure, elle s'avère en fait utile. Considérez ce programme, qui ajoute les en-têtes de copyright en place (grâce à un autre Perlism-i
) à chaque fichier mentionné sur la ligne de commande:Crédit à:
la source
idx
sera le "numéro de ligne" dans le fichier virtuel concaténant toutes les entrées, plutôt que le numéro de ligne pour chaque fichier individuel.#!/usr/bin/env ruby -i
ligne ne fonctionne pas sous Linux: stackoverflow.com/q/4303128/735926Ruby fournit une autre façon de gérer STDIN: l'indicateur -n. Il traite l'intégralité de votre programme comme étant à l'intérieur d'une boucle sur STDIN (y compris les fichiers passés comme arguments de ligne de commande). Voir par exemple le script 1 ligne suivant:
la source
#!/usr/bin/env ruby -n
ne fonctionnera pas, car "ruby -n" sera passé à / usr / bin / env comme seul argument. Voir cette réponse pour plus de détails. Le script va fonctionner si elle est exécutée avecruby -n script.rb
explicitement.Je ne sais pas exactement ce dont vous avez besoin, mais j'utiliserais quelque chose comme ceci:
Notez que parce que le tableau ARGV est vide avant le premier
gets
, Ruby n'essaiera pas d'interpréter l'argument comme un fichier texte à partir duquel lire (comportement hérité de Perl).Si stdin est vide ou s'il n'y a pas d'arguments, rien n'est imprimé.
Peu de cas de test:
la source
Quelque chose comme ça peut-être?
Exemple:
la source
Ceci est inspiré par Perl:
la source
Rapide et simple:
STDIN.gets.chomp == 'YES'
la source
J'ajouterai que pour utiliser
ARGF
avec des paramètres, vous devez effacerARGV
avant d'appelerARGF.each
. C'est parceARGF
que traitera toutARGV
comme un nom de fichier et lira les lignes à partir de là en premier.Voici un exemple d'implémentation «tee»:
la source
Je fais quelque chose comme ça:
la source
Il semble que la plupart des réponses supposent que les arguments sont des noms de fichiers contenant du contenu à envoyer à la stdin. En dessous, tout est traité comme de simples arguments. Si STDIN provient du TTY, il est ignoré.
Les arguments ou stdin peuvent être vides ou contenir des données.
la source