ruby - как правильно разобрать различное количество аргументов командной строки - PullRequest
5 голосов
/ 02 февраля 2012

n00b вопрос оповещения!вот проблема: я создаю сценарий оболочки, который принимает минимум 3 аргумента: строку, номер строки и хотя бы один файл.

Я написал скрипт, который будет принимать ТОЛЬКО 3 аргумента, но я не знаю, как обрабатывать несколько аргументов имени файла.

вот соответствующие части моего кода (пропуская запись обратно в файл и т. д.):

#!/usr/bin/env ruby

the_string = ARGV[0] 
line_number = ARGV[1]
the_file = ARGV[2] 

def insert_script(str, line_n, file)
  f = file
  s = str
  ln = line_n.to_i

  if (File.file? f)
    read_in(f,ln,s)
  else 
    puts "false"
  end
end

def read_in(f,ln,s)
  lines = File.readlines(f)
  lines[ln] = s + "\n"
  return lines
end

# run it
puts insert_script(the_string, line_number, the_file)

теперь язнаю, что легко написать блок, который будет перебирать ВСЕ аргументы:

ARGV.each do |a|
   puts a 
end

, но мне нужно ТОЛЬКО циклически перебирать аргументы от ARGV [2] (первое имя файла) до последнего имени файла,

Я знаю, что должен быть - как минимум - хотя бы один простой способ сделать это, но я просто не могу понять, что это на данный момент!

в любом случае - я был бы более чем счастлив, если бы кто-то мог просто указать мне на учебник или пример, я уверен, что есть много там - но я не могу их найти.

спасибо

Ответы [ 5 ]

7 голосов
/ 02 февраля 2012

Не могли бы вы использовать полезный камень? Trollop отлично подходит для синтаксического анализа командной строки, поскольку он автоматически предоставляет вам сообщения справки, длинные и короткие ключи командной строки и т. Д.

require 'trollop'

opts = Trollop::options do
  opt :string, "The string", :type => :string
  opt :line, "line number", :type => :int
  opt :file, "file(s)", :type => :strings
end

p opts 

Когда я называю это «commandline.rb» и запускаю его:

$ ruby commandline.rb --string "foo bar" --line 3 --file foo.txt bar.txt

{:string=>"foo bar", :line=>3, :file=>["foo.txt", "bar.txt"], :help=>false, :string_given=>true, :line_given=>true, :file_given=>true}
5 голосов
/ 02 февраля 2012

Если вы измените массив ARGV, чтобы удалить элементы, которые вас больше не интересуют, рассматривая как имена файлов, вы можете рассматривать все оставшиеся элементы как имена файлов и перебирать их содержимое с помощью ARGF.

Это глоток, небольшой пример продемонстрирует это легче:

argf.rb:

#!/usr/bin/ruby

str = ARGV.shift
line = ARGV.shift

ARGF.each do |f|
    puts f
end
$ ./argf.rb one two argf.rb argf.rb 
#!/usr/bin/ruby

str = ARGV.shift
line = ARGV.shift

ARGF.each do |f|
    puts f
end
#!/usr/bin/ruby

str = ARGV.shift
line = ARGV.shift

ARGF.each do |f|
    puts f
end
$ 

Есть два копии файла argf.rb напечатаны на консоли, потому что я дважды дал имя командной строки argf.rb в командной строке.Он был открыт и повторен один раз для каждого упоминания.

Если вы хотите работать с файлами как с файлами, а не читать их содержимое, вы можете просто изменить массив ARGV и затем напрямую использовать оставшиеся элементы.

3 голосов
/ 02 февраля 2012

Каноническим способом является использование shift, например:

the_string = ARGV.shift
line_number = ARGV.shift
ARGV.each do |file|
  puts insert_script(the_string, line_number, the_file)
end
2 голосов
/ 02 февраля 2012

Альтернативный (и несколько более уродливый) трюк, если вы не хотите использовать другую библиотеку или изменить массив ARGV, это использовать .upto

2.upto(ARGV.length-1) do |i|
    puts ARGV[i]
end
2 голосов
/ 02 февраля 2012

Взгляните на OptionParser - http://ruby -doc.org / stdlib-1.9.3 / libdoc / optparse / rdoc / OptionParser.html .Это позволяет вам указать количество аргументов, будь то обязательные или необязательные, для обработки ошибок, таких как MissingArgument или InvalidOption.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...