Getopt::Long
est simplement l'analyse syntaxique de la liste @ARGV
comme prévu au programme Perl. Si les paramètres sont des entrées séparées dans la liste @ARGV
, Getopt::Long
les analysera de cette manière. Votre problème est que le shell place chaque argument comme un paramètre séparé puisqu'il n'y a pas de guillemets autour d'eux.
Votre choix est soit munge les paramètres avant votre script Perl exécute, ou par munging @ARGV
lui-même de combiner les paramètres dans les valeurs qu'ils sont supposés être.
Pour la première option, vous pouvez utiliser sed
pour prendre la sortie de votre programme et ajouter les citations manquantes. Si vous êtes programme crache toujours des champs comme ceci:
prog_name -filter_arg +define BOOST +noconvtest +actuate-long -disp_arg +define size=40 res=30
Vous pourriez tuyau par sed
comme ceci:
$ orig_prog | sed -e 's/filter_arg /filter_arg "/' -e 's/ -disp_arg /" -disp_arg "/' -e 's/$/"/'
Ou ceci:
$ orig_prog | sed -e 's/^\(.*\) -filter_arg \(.*\) -disp_arg \(.*\)$/\1 -filter_arg "\2" -disp_arg "\3"/'
Cela va mettre les citations autour de vos paramètres et il ressemblera à ceci:
prog_name -filter_arg "+define BOOST +noconvtest +actuate-long" -disp_arg "+define size=40 res=30"
De cette façon, @ARGV
sera configuré correctement pour que la fonction GetOptions
fonctionne comme vous le souhaitez.
L'autre façon est de munge @ARGV
une fois que vous êtes programme Perl fonctionne avant d'appeler GetOptions
:
my $value;
my @newArgv;
foreach my $param (@ARGV) {
if ($param =~ /^-/) {
if ($value) {
push (@newArgv, $value);
$value = "";
}
push(@newArgv, $param);
} else {
$value = $value ? "$value $param" : "$param";
}
}
push (@newArgv, $value) if ($value);
@ARGV = @newArgv;
Dans l'exemple ci-dessus, @ARGV
aura les valeurs suivantes:
@ARGV[0] = -filter_arg
@ARGV[1] = +define BOOST +noconvtest +actuate-long
@ARGV[2] = -disp_arg
@ARGV[3] = +define size=40 res=30
Et , Getopts::Long
devrait maintenant fonctionner comme vous le souhaitez. Petite note: Dans les nouvelles versions de Getopt::Long
, vous pouvez utiliser d'autres baies en plus de @ARGV
. Vous mettez simplement le tableau que vous voulez utiliser comme premier argument dans GetOptions
:
use Getopt::Long qw(GetOptionsFromArray);
GetOptionsFromArray (
\@newArgs,
"filter_arg=s" => \$filter_arg,
"disp_arg=s" => \$disp_arg,
);
Merci beaucoup Axeman, David et Colin. Vraiment apprécier votre réponse rapide. Et dans le véritable esprit de Perl, vous avez montré comment le problème peut être résolu de multiples façons! J'ai beaucoup appris après chacune de vos publications. Meilleurs voeux. – Silver2010
Manque le point que les options ont été divisées par le shell, pas par Perl. – Demi