Getopt::Long 将带空格的字符串获取到变量中

发布于 2024-11-30 00:52:54 字数 282 浏览 3 评论 0原文

我正在制作一个 perl 脚本,它使用 Getopt::Long 来解析命令行参数。但是,我有一个参数可以接受字符串(带空格)。如何将整个字符串放入变量中。例如:

./script.pl --string=blah blah blah blah yup --another-opt

我需要变量 $string 中的“blah blah blah blah yup”。我知道 Getopt::Long 支持一个参数的多个输入当你知道你将有多少(我不知道)。这可能吗?

I'm making a perl script which uses Getopt::Long to parse command line arguments. However, I have an argument which can accept a string (with spaces). How can I get the whole string into a variable. For example:

./script.pl --string=blah blah blah blah yup --another-opt

I need "blah blah blah blah yup" in variable $string. I know Getopt::Long supports multiple inputs for one argument when you know how many you will have (which I do not). Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

等风来 2024-12-07 00:52:54

您需要在参数周围加上引号:

./script.pl --string="blah blah blah blah yup" --another-opt

或转义空格:

./script.pl --string=blah\ blah\ blah\ blah\ yup --another-opt

You need to either put quotes around the argument:

./script.pl --string="blah blah blah blah yup" --another-opt

or escape the spaces:

./script.pl --string=blah\ blah\ blah\ blah\ yup --another-opt
☆獨立☆ 2024-12-07 00:52:54

这实际上是对 MaxMackie 对 Ernest 答案的问题的答复,但它太长了,所以这里是:

您的脚本永远不会看到引号,只有传递参数的 shell。当您调用脚本(或程序)时,较低级别上发生的情况是使用数组中的多个参数来调用该命令。 shell 通常根据空格分割参数。您的程序现在看到的是:

[0]./script.pl
[1]--string=blah
[2]blah
[3]blah
[4]blah
[5]yup
[6]--another-opt

在字符串周围加上引号或转义它会导致以下结果:

[0]./script.pl
[1]--string=blah blah blah blah yup
[2]--another-opt

Shell(特别是 bash,我确信其他的)允许随意散布不带空格的引号。 ls -"l""h"ls -lh 相同,因此您可以执行 "--string=blah blah"--string="blah blah"。使用 getopt 对各个参数进行解析,让您可以将它们打乱顺序并使用 --long-name-l 发生在所有内容都转换为数组项之后,并且传递给程序。外壳与此无关。

This is really a reply to MaxMackie's question on Ernest's answer, but it's too long, so here goes:

Your script never sees the quotes, only the shell that is passing the arguments. When you call a script (or program), what is happening on a lower level is that the command is called with several arguments in an array. The shell normally splits arguments up based on whitespace. What your program sees right now is:

[0]./script.pl
[1]--string=blah
[2]blah
[3]blah
[4]blah
[5]yup
[6]--another-opt

Putting quotes around the string or escaping it results in in this:

[0]./script.pl
[1]--string=blah blah blah blah yup
[2]--another-opt

Shells (bash in particular, others I'm sure) allows interspersing quotes without spaces as much as you like. ls -"l""h" is the same as ls -lh, hence you an do "--string=blah blah" or --string="blah blah". The parsing of the individual arguments with getopt that lets you put them out of order and use --long-name or -l happens after everything is turned into an array item and passed to the program. The shell has nothing to do with that.

爱,才寂寞 2024-12-07 00:52:54

虽然我当然同意您应该逃避参数,但如果像我一样您遇到无法轻松控制输入的情况,那么实际上可以使用 Getopt::Long 来做到这一点。

示例: [https://www.jdoodle.com/a/oHG]

use strict;
use Getopt::Long qw(GetOptions);


my @spaces_string;

GetOptions('test=s{1,}' => \@spaces_string);
printf "String is: '%s'\n" ,join " ",@spaces_string;

您是将您的选项定义为具有 1 个或多个值,将其分配给一个数组,然后将其连接回一个字符串。

这在文档的“具有多个值的选项”部分中有很好的解释: http://perldoc.perl.org/Getopt/Long.html#Options-with-multiple-values

While I certainly agree that you should escape the arguments, if like me you have situation where you don't easily have control over the input then it is actually possible to do this with Getopt::Long.

Example: [https://www.jdoodle.com/a/oHG]

use strict;
use Getopt::Long qw(GetOptions);


my @spaces_string;

GetOptions('test=s{1,}' => \@spaces_string);
printf "String is: '%s'\n" ,join " ",@spaces_string;

You are defining your option as having 1 or more values, assign it to an array and then join it back into a string.

This is explained quite well under the 'Options with multiple values' section of the documentation: http://perldoc.perl.org/Getopt/Long.html#Options-with-multiple-values

平生欢 2024-12-07 00:52:54

现在给我这个谜语...在下面的场景中,我想通过 shell 命令生成一个带引号的命令行参数,然后将其传递给 Perl 脚本,如下所示:

script.pl `echo --string \"blah blah yup\"`

问题是,GetOptions ("string=s " => \$string) 将字符串的值设置为

"blah

包含初始双引号字符并在第一个空格处断开。 echo 命令本身会输出带有看起来桃色的带引号字符串的参数:

--string "blah blah yup"

如果我在没有 echo 的情况下调用 script.pl --string "blah blah yup" ,则包含字符串的空白会在Perl 脚本如预期。

我认为也许反引号是问题所在,但这些变体会产生相同的结果:

script.pl $(echo --string \"blah blah yup\")
script.pl $(echo "--string \"blah blah yup\"")
script.pl $(echo --string \"blah\ blah\ yup\")
script.pl $(echo '--string \"blah blah yup\"')

尽管最后一个示例导致 string=\"blah (包含初始反斜杠 双引号字符)。

看起来从 shell 命令的 STDOUT 返回的输出并没有被 Perl 的参数解析机制以与输入到命令行中的字符串相同的方式处理,但这种明显缺乏字符串可替换性的情况有些令人惊讶。可能是由于我不理解 bash 的某些方面(顺便说一句,我在 Darwin 上使用 Perl 5.24 和 Linux 上使用 5.16 进行了测试)

Now riddle me this... in the following scenario, I want to generate a quoted command-line argument via a shell command which then gets passed to a Perl script, like this:

script.pl `echo --string \"blah blah yup\"`

Trouble is, GetOptions ("string=s" => \$string) sets string's value to

"blah

containing the initial double-quote character and breaking at the first whitespace. The echo command by itself outputs the parameter with a quoted string that looks peachy:

--string "blah blah yup"

and if I call script.pl --string "blah blah yup" without the echo, the whitespace containing string gets set in the Perl script as expected.

I thought that maybe the backticks were the issue, but the same results ensue with these variants:

script.pl $(echo --string \"blah blah yup\")
script.pl $(echo "--string \"blah blah yup\"")
script.pl $(echo --string \"blah\ blah\ yup\")
script.pl $(echo '--string \"blah blah yup\"')

though that last example leads to string=\"blah (containing the initial backslash and double quote character).

Seems like the output returned from a shell command's STDOUT is not being handled the same way by Perl's argument parsing machinery as a string that is typed into the command-line. This apparent lack of string fungibility is somewhat surprising, but probably owing to some aspect of bash I don't understand. (Btw, I tested this with Perl 5.24 on Darwin and 5.16 on Linux)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文