我想在Ruby中处理命令行输入:
> cat input.txt | myprog.rb
> myprog.rb < input.txt
> myprog.rb arg1 arg2 arg3 ...
最好的方法是什么?我特别想处理空白的STDIN,我希望有一个优雅的解决方案。
#!/usr/bin/env ruby
STDIN.read.split("\n").each do |a|
puts a
end
ARGV.each do |b|
puts b
end
我想在Ruby中处理命令行输入:
> cat input.txt | myprog.rb
> myprog.rb < input.txt
> myprog.rb arg1 arg2 arg3 ...
最好的方法是什么?我特别想处理空白的STDIN,我希望有一个优雅的解决方案。
#!/usr/bin/env ruby
STDIN.read.split("\n").each do |a|
puts a
end
ARGV.each do |b|
puts b
end
当前回答
我是这样做的:
all_lines = ""
ARGV.each do |line|
all_lines << line + "\n"
end
puts all_lines
其他回答
也许是这样的?
#/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
例子:
> 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
以下是我在收藏的一些不知名的Ruby代码中发现的一些东西。
因此,在Ruby中,Unix命令的简单无铃实现 猫会是: # !/usr/bin/env红宝石 把ARGF.read ——https://web.archive.org/web/20080725055721/http: / / www.oreillynet.com/ruby/blog/2007/04/trivial_scripting_with_ruby.html评论- 565558
ARGF在输入方面是你的朋友;它是一个虚拟文件,从命名文件或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
Thank goodness we didn’t get the diamond operator in Ruby, but we did get ARGF as a replacement. Though obscure, it actually turns out to be useful. Consider this program, which prepends copyright headers in-place (thanks to another Perlism, -i) to every file mentioned on the command-line: #!/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. #++ — http://blog.nicksieger.com/articles/2007/10/06/obscure-and-ugly-perlisms-in-ruby
信贷:
https://web.archive.org/web/20080725055721/http://www.oreillynet.com/ruby/blog/2007/04/trivial_scripting_with_ruby.html#comment-565558 http://blog.nicksieger.com/articles/2007/10/06/obscure-and-ugly-perlisms-in-ruby
我要补充一点,为了带参数使用ARGF,你需要在调用ARGF.each之前清除ARGV。这是因为ARGF将ARGV中的任何内容视为文件名,并首先从那里读取行。
这是一个'tee'实现的例子:
File.open(ARGV[0], 'w') do |file|
ARGV.clear
ARGF.each do |line|
puts line
file.write(line)
end
end
我不太清楚你需要什么,但我会用这样的东西:
#!/usr/bin/env ruby
until ARGV.empty? do
puts "From arguments: #{ARGV.shift}"
end
while a = gets
puts "From stdin: #{a}"
end
注意,因为ARGV数组在第一次获取之前是空的,Ruby不会尝试将参数解释为要读取的文本文件(行为继承自Perl)。
如果stdin为空或没有参数,则不打印任何内容。
很少的测试用例:
$ 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!
Ruby提供了另一种处理STDIN的方法:-n标志。它将整个程序视为在STDIN上的循环中(包括作为命令行参数传递的文件)。参见以下一行脚本:
#!/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