Saya ingin berurusan dengan input baris perintah di Ruby:
> cat input.txt | myprog.rb
> myprog.rb < input.txt
> myprog.rb arg1 arg2 arg3 ...
Apa cara terbaik untuk melakukannya? Secara khusus saya ingin berurusan dengan STDIN kosong, dan saya berharap untuk solusi yang elegan.
#!/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
file dilampirkan ke stdin ; shell mengelola ini untuk Anda.Jawaban:
Berikut adalah beberapa hal yang saya temukan dalam koleksi Ruby yang tidak jelas.
Jadi, di Ruby, implementasi no-bells sederhana dari perintah Unix
cat
adalah:ARGF
adalah teman Anda dalam hal input; itu adalah file virtual yang mendapatkan semua input dari file bernama atau semua dari STDIN.Syukurlah kami tidak mendapatkan operator berlian di Ruby, tetapi kami memang mendapatkan
ARGF
sebagai penggantinya. Meski tidak jelas, ternyata itu bermanfaat. Pertimbangkan program ini, yang menambahkan header hak cipta di tempat (berkat Perlism lain,-i
) ke setiap file yang disebutkan pada baris perintah:Kredit untuk:
sumber
idx
akan menjadi "nomor baris" dalam file virtual yang menggabungkan semua input, bukan nomor baris untuk setiap file individu.#!/usr/bin/env ruby -i
baris ini tidak berfungsi di Linux: stackoverflow.com/q/4303128/735926Ruby menyediakan cara lain untuk menangani STDIN: Bendera -n. Ini memperlakukan seluruh program Anda sebagai berada di dalam loop di atas STDIN, (termasuk file yang dilewatkan sebagai argumen baris perintah). Lihat misalnya skrip 1-baris berikut:
sumber
#!/usr/bin/env ruby -n
tidak akan berfungsi, karena "ruby -n" akan diteruskan ke / usr / bin / env sebagai satu-satunya argumen. Lihat jawaban ini untuk lebih jelasnya. Script akan bekerja jika dijalankanruby -n script.rb
secara eksplisit.Saya tidak yakin apa yang Anda butuhkan, tetapi saya akan menggunakan sesuatu seperti ini:
Perhatikan bahwa karena array ARGV kosong sebelum pertama
gets
, Ruby tidak akan mencoba menafsirkan argumen sebagai file teks untuk dibaca (perilaku diwarisi dari Perl).Jika stdin kosong atau tidak ada argumen, tidak ada yang dicetak.
Beberapa kasus uji:
sumber
Mungkin sesuatu seperti ini?
Contoh:
sumber
Ini terinspirasi oleh Perl:
sumber
Cepat dan sederhana:
STDIN.gets.chomp == 'YES'
sumber
Saya akan menambahkan itu untuk digunakan
ARGF
dengan parameter, Anda harus menghapusARGV
sebelum memanggilARGF.each
. Ini karenaARGF
akan memperlakukan apa punARGV
sebagai nama file dan membaca baris dari sana terlebih dahulu.Berikut ini contoh penerapan 'tee':
sumber
Saya melakukan sesuatu seperti ini:
sumber
Tampaknya sebagian besar jawaban dengan asumsi argumen adalah nama file yang berisi konten yang akan di cat ke stdin. Di bawah ini semua diperlakukan hanya sebagai argumen. Jika STDIN dari TTY, maka diabaikan.
Argumen atau stdin dapat kosong atau memiliki data.
sumber