Chcę poradzić sobie z danymi wiersza poleceń w Ruby:
> cat input.txt | myprog.rb
> myprog.rb < input.txt
> myprog.rb arg1 arg2 arg3 ...
Jak najlepiej to zrobić? W szczególności chcę poradzić sobie z czystym STDIN i mam nadzieję na eleganckie rozwiązanie.
#!/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
plik jest dołączony do standardowego wejścia ; powłoka zarządza tym za ciebie.Odpowiedzi:
Oto kilka rzeczy, które znalazłem w mojej kolekcji niejasnego Ruby.
Tak więc w Rubim prostą implementacją komendy uniksowej
cat
byłoby:ARGF
jest twoim przyjacielem, jeśli chodzi o wkład; jest to plik wirtualny, który pobiera wszystkie dane wejściowe z nazwanych plików lub wszystkie z STDIN.Dzięki Bogu nie dostaliśmy operatora diamentów w Ruby, ale dostaliśmy go
ARGF
jako zamiennik. Choć niejasne, w rzeczywistości okazuje się przydatne. Rozważ ten program, który umieszcza nagłówki praw autorskich w miejscu (dzięki innemu Perlizmowi-i
) do każdego pliku wymienionego w wierszu poleceń:Kredyt dla:
źródło
idx
będzie to „numer wiersza” w pliku wirtualnym łączącym wszystkie dane wejściowe, a nie numer wiersza dla każdego pojedynczego pliku.#!/usr/bin/env ruby -i
linia nie działa w systemie Linux: stackoverflow.com/q/4303128/735926Ruby zapewnia inny sposób obsługi STDIN: flaga -n. Traktuje cały program jako znajdujący się w pętli nad STDIN (w tym pliki przekazywane jako argumenty wiersza poleceń). Zobacz np. Następujący 1-wierszowy skrypt:
źródło
#!/usr/bin/env ruby -n
nie będzie działał, ponieważ „ruby -n” zostanie przekazany do / usr / bin / env jako jedyny argument. Zobacz tę odpowiedź, aby uzyskać więcej informacji. Skrypt będzie działał, jeśli zostanie uruchomionyruby -n script.rb
jawnie.Nie jestem pewien, czego potrzebujesz, ale użyłbym czegoś takiego:
Zauważ, że ponieważ tablica ARGV jest pusta przed pierwszym
gets
, Ruby nie będzie próbowała interpretować argumentu jako pliku tekstowego, z którego można czytać (zachowanie odziedziczone po Perlu).Jeśli standardowe wejście jest puste lub nie ma żadnych argumentów, nic nie jest drukowane.
Kilka przypadków testowych:
źródło
Może coś takiego?
Przykład:
źródło
Inspiruje się to Perl:
źródło
Szybki i prosty:
STDIN.gets.chomp == 'YES'
źródło
Dodam, że aby użyć
ARGF
parametrów, musisz wyczyścićARGV
przed wywołaniemARGF.each
. Jest tak, ponieważARGF
traktuje wszystkoARGV
jako nazwę pliku i najpierw odczytuje wiersze.Oto przykładowa implementacja „tee”:
źródło
Robię coś takiego:
źródło
Wydaje się, że większość odpowiedzi zakłada, że argumentami są nazwy plików zawierające treść, która ma zostać przypisana do standardowego wejścia. Poniżej wszystko jest traktowane tylko jako argumenty. Jeśli STDIN pochodzi z TTY, to jest ignorowane.
Argumenty lub standardowe wejście może być puste lub zawierać dane.
źródło