Geriausia praktika su STDIN Ruby?

Noriu susidoroti su komandų eilutės įvedimu Ruby:

 > cat input.txt | myprog.rb > myprog.rb < input.txt > myprog.rb arg1 arg2 arg3 ... 

Koks yra geriausias būdas tai padaryti? Visų pirma noriu susidoroti su tuščiu STDIN ir tikiuosi elegantiško sprendimo.

 #!/usr/bin/env ruby STDIN.read.split("\n").each do |a| puts a end ARGV.each do |b| puts b end 
282
07 нояб. nustatytas griflet 07 nov. 2008-11-07 22:14 '08 10:14 val. 2008-11-07 22:14
@ 9 atsakymai

Žemiau yra keletas dalykų, kuriuos suradau savo neaiškių Ruby kolekcijoje.

Taigi, Ruby, paprastas „Unix“ cat „be-varpų“ komandos įgyvendinimas bus:

 #!/usr/bin/env ruby puts ARGF.read 

ARGF yra jūsų draugas, kai kalbama apie įvestį; Tai virtualus failas, kuris gauna visus duomenis iš pavadintų failų arba visus STDIN.

 ARGF.each_with_index do |line, idx| print ARGF.filename, ":", idx, ";", line end # print all the lines in every file passed via command line that contains login ARGF.each do |line| puts line if line =~ /login/ end 

Ačiū Dievui, mes ARGF deimantų operatoriaus Ruby, bet mes turime ARGF kaip pakaitalą. Nors neaišku, iš tikrųjų tai naudinga. Apsvarstykite šią programą, kuri prideda autorių teisių antraštes į vietą (dėka skirtingo perlizmo, -i ) kiekvienam komandų eilutėje nurodytam failui:

 #!/usr/bin/env ruby -i Header = DATA.read ARGF.each_line do |e| puts Header if ARGF.pos - e.length == 0 puts e end __END__ #-- # Copyright (C) 2007 Fancypants, Inc. #++ 

Kreditas:

367
08 нояб. Atsakymą pateikė Jonke 08 lapkritis 2008-11-08 01:29 '08, 1:29 am 2008-11-08 01:29

Ruby suteikia kitą būdą, kaip elgtis su STDIN: -n vėliava. Ji traktuoja jūsų visą programą kaip kilpą virš STDIN (įskaitant failus, perduotus komandų eilutės argumentais). Žiūrėkite šią 1 scenarijų eilutę:

border=0
 #!/usr/bin/env ruby -n #example.rb puts "hello: #{$_}" #prepend 'hello:' to each line from STDIN #these will all work: # ./example.rb < input.txt # cat input.txt | ./example.rb # ./example.rb input.txt 
37
03 марта '11 в 6:13 2011-03-03 06:13 atsakymą pateikė Bill Caputo kovo 3 d. 11 d. 6:13 2011-03-03 06:13

Aš nesu tikras, ko jums reikia, bet norėčiau naudoti tokį dalyką:

 #!/usr/bin/env ruby until ARGV.empty? do puts "From arguments: #{ARGV.shift}" end while a = gets puts "From stdin: #{a}" end 

Atkreipkite dėmesį, kad, kadangi ARGV masyvas yra tuščias prieš pirmą kartą, Ruby nesistengs interpretuoti argumento kaip tekstinio failo, iš kurio skaityti (elgesys iš Perl).

Jei stdin yra tuščias arba nėra argumentų, nieko spausdinama.

Keli bandymų atvejai:

 $ cat input.txt | ./myprog.rb From stdin: line 1 From stdin: line 2 $ ./myprog.rb arg1 arg2 arg3 From arguments: arg1 From arguments: arg2 From arguments: arg3 hi! From stdin: hi! 
28
07 нояб. Atsakymą pateikė Damir Zekić 07.11 . 2008-11-07 22:51 '08 at 10:51 pm 2008-11-07 22:51

Ar tai įmanoma?

 #/usr/bin/env ruby if $stdin.tty? ARGV.each do |file| puts "do something with this file: #{file}" end else $stdin.each_line do |line| puts "do something with this line: #{line}" end end 

Pavyzdys:

 > cat input.txt | ./myprog.rb do something with this line: this do something with this line: is do something with this line: a do something with this line: test > ./myprog.rb < input.txt do something with this line: this do something with this line: is do something with this line: a do something with this line: test > ./myprog.rb arg1 arg2 arg3 do something with this file: arg1 do something with this file: arg2 do something with this file: arg3 
15
07 нояб. Atsakymas suteikiamas Magnus Holm, lapkričio 7 d. 2008-11-07 23:53 '08, 23:53, 2008-11-07 23:53
 while STDIN.gets puts $_ end while ARGF.gets puts $_ end 

Tai įkvepia Perl:

 while(<STDIN>){ print "$_\n" } 
11
10 июля '12 в 0:52 2012-07-10 00:52 atsakymas pateikiamas texasbruce liepos 10 d. 12 val. 0:52 2012-07-10 00:52

Aš tai darau:

 all_lines = "" ARGV.each do |line| all_lines << line + "\n" end puts all_lines 
1
31 марта '16 в 13:19 2016-03-31 13:19 atsakymas pateikiamas wired00 kovo 31 d. 16, 13:19 2016-03-31 13:19

Aš pridėsiu, kad norint naudoti ARGF su parametrais, prieš skambindami ARGF.each turite išvalyti ARGF.each . Taip yra dėl to, kad ARGF apdoros kažką ARGV kaip failo pavadinimą ir pirmiausia perskaitys eilutes.

Štai pavyzdys „tee“ įgyvendinimui:

 File.open(ARGV[0], 'w') do |file| ARGV.clear ARGF.each do |line| puts line file.write(line) end end 
1
20 янв. Richard Nienaber atsakymas sausio 20 d 2016-01-20 20:15 '16 at 20:15 2016-01-20 20:15

Greitas ir paprastas:

STDIN.gets.chomp == 'YES'

0
11 нояб. Atsakymą pateikė Jose Albanas lapkričio 11 d. 2016-11-11 15:00 '16 at 15:00 2016-11-11 15:00

Atrodo, kad dauguma atsakymų daroma prielaida, kad argumentai yra failų pavadinimai, kuriuose yra stdino „catdd“ turinys. Žemiau viskas laikoma tik argumentu. Jei STDIN yra iš TTY, tada jis ignoruojamas.

 $ cat tstarg.rb while a=(ARGV.shift or (!STDIN.tty? and STDIN.gets) ) puts a end 

Argumentai arba stdin gali būti tušti arba turėti duomenų.

 $ cat numbers 1 2 3 4 5 $ ./tstarg.rb abc < numbers a b c 1 2 3 4 5 
0
12 окт. Howard Barina atsakymas spalio 12 d 2016-10-12 16:01 '16, 16:01 pm 2016-10-12 16:01

Kiti klausimai apie žymes arba Užduoti klausimą