2010-03-15 10 views
24

tengo que analizar una línea de comandos comocómo analizar un argumento sin nombre con optparse de Ruby

script.rb <mandatory filename> [options] 

con optparse.

Claro que puedo escribir algunos códigos personalizados para manejar el nombre del archivo, luego paso ARGV a optparse, pero ¿tal vez hay una forma más sencilla de hacerlo?

EDITAR: hay otra manera hacky de analizar esa línea de comandos, y es pasar ['--mandatory-filename'] + ARGV a optparse, luego manejar la opción --mandatory-filename.

+0

Ver a continuación las respuestas, definitivamente; sin embargo, le recomendaría intercambiar sus parámetros 'obligatorios de nombre de archivo' y' opciones'.Por lo general, los argumentos que no cambian son los últimos en una línea de comandos, a menos que tenga una razón particular para hacerlo –

Respuesta

38

Primero parse! con optparse, luego escanee el ARGV y eleve si ARGV está vacío. De este modo:

op.parse! 
filename = ARGV.pop 
raise "Need to specify a file to process" unless filename 

El nombre del archivo obligatoria no será procesada por el OptionParser y será dejado para usted en ARGV - si no está ahí, simplemente levantar manualmente.

+1

Use algo como 'op.banner + = ''' para ajustar la línea 'Uso:' según corresponda . – sschuberth

+1

no sería 'ARGV.shift' en lugar de' ARGV.pop' ¿sería mejor si quisiéramos expandir a varios parámetros necesarios? – nhed

+0

nhed, sí, buena idea ya que generalmente se requieren primero uno o dos argumentos posicionales y estos últimos son opcionales (por ejemplo, con 'zip' primero tienes que poner el nombre del archivo, y luego una lista de archivos que se comprimen en el archivo). –

0

Optparse solo tiene argumentos con parámetros, AFAIK. La forma "correcta" de manejar su nombre de archivo es tratarlo fuera de optparse. Publiqué un código de ejemplo para esto en respuesta a la pregunta this.

Por cierto, es una línea de comandos bastante inusual. Si es solo para ti, está bien, pero es probable que otros lo encuentren bastante contrario a la intuición. Sería más normal tener: script.rb [options] <filename> ...

+0

Gracias, punto tomado –

+0

OptParse maneja todo tipo de opciones. Hace banderas, parámetros, parámetros opcionales, listas, booleanos. Consulte el [Ejemplo completo] (http://ruby-doc.org/ruby-1.9/classes/OptionParser.html) para obtener más información. –

9

Sólo hacer un seguimiento de lo que Julik y Shadowfirebird dijeron: Al analizar con OptionParser tenga en cuenta que parse! y parse tienen una funcionalidad diferente. El primero eliminará todos los argumentos que entienda de la matriz pasada donde los dejará. Esto cambia sus condiciones para determinar si el argumento requerido está presente.

3

A pesar de que no se aplica a todas las situaciones, a menudo es agradable ser capaz de procesar varios archivos en una sola línea de comandos, tales como:

script.rb [options] file1 file2 ... 

fichero1 es obligatorio, pero es fichero2 y más allá Opcional.

La mejor manera que conozco para hacer esto sigue esta convención:

options = {} 
optparse = OptionParser.new do |opts| 
    opts.banner = "Usage: script.rb [options] file1 file2 ..." 

    opts.on('-a', '--an-option ARG', 'Set some option') do |arg| 
    options[:a] = arg 
    end 

    ... 
end 
optparse.parse! 

# Check required conditions 
if ARGV.empty? 
    puts optparse 
    exit(-1) 
end 

Si no se proporcionan archivos, un mensaje de ayuda se mostrará con el uso de la bandera y una descripción de las opciones. Si los archivos están presentes, serán lo único que queda en ARGV.

1

No estoy seguro de si se ha agregado recientemente, pero ninguna de las respuestas anteriores menciona que optparse.parse devolverá el valor ARGV después de eliminar las opciones analizadas.

Si hace esto:

rest = optparse.parse! 

Usted recibirá una matriz con los fichero/s dados (a lo largo de las opciones desconocidos). De esta manera, no tiene que preocuparse si las opciones vienen antes o después del archivo.

Cuestiones relacionadas