在 Bash 中使用 getopts 检索单个选项的多个参数
我需要 getopts
方面的帮助。
我创建了一个 Bash 脚本,运行时如下所示:
$ foo.sh -i env -d directory -s subdirectory -f file
在处理每个标志的一个参数时它可以正常工作。但是,当我从每个标志调用多个参数时,我不确定如何从 getopts 中的变量中提取多个变量信息。
while getopts ":i:d:s:f:" opt
do
case $opt in
i ) initial=$OPTARG;;
d ) dir=$OPTARG;;
s ) sub=$OPTARG;;
f ) files=$OPTARG;;
esac
done
获取选项后,我想从变量构建目录结构
foo.sh -i test -d directory -s subdirectory -s subdirectory2 -f file1 file2 file3
那么目录结构将是有
/test/directory/subdirectory/file1
/test/directory/subdirectory/file2
/test/directory/subdirectory/file3
/test/directory/subdirectory2/file1
/test/directory/subdirectory2/file2
/test/directory/subdirectory2/file3
什么想法吗?
I need help with getopts
.
I created a Bash script which looks like this when run:
$ foo.sh -i env -d directory -s subdirectory -f file
It works correctly when handling one argument from each flag. But when I invoke several arguments from each flag I am not sure how to pull the multiple variable information out of the variables in getopts
.
while getopts ":i:d:s:f:" opt
do
case $opt in
i ) initial=$OPTARG;;
d ) dir=$OPTARG;;
s ) sub=$OPTARG;;
f ) files=$OPTARG;;
esac
done
After grabbing the options I then want to build directory structures from the variables
foo.sh -i test -d directory -s subdirectory -s subdirectory2 -f file1 file2 file3
Then the directory structure would be
/test/directory/subdirectory/file1
/test/directory/subdirectory/file2
/test/directory/subdirectory/file3
/test/directory/subdirectory2/file1
/test/directory/subdirectory2/file2
/test/directory/subdirectory2/file3
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
您可以多次使用同一选项并将所有值添加到数组中。
对于这里非常具体的原始问题,Ryan 的 mkdir -p 解决方案显然是最好的。
但是,对于使用 getopts 从同一选项获取多个值这一更普遍的问题,
输出为:
You can use the same option multiple times and add all values to an array.
For the very specific original question here, Ryan's
mkdir -p
solution is obviously the best.However, for the more general question of getting multiple values from the same option with getopts, here it is:
The output would be:
我知道这个问题已经很老了,但我想把这个答案放在这里,以防有人来寻找答案。
像 BASH 这样的 shell 已经支持像这样递归地创建目录,所以实际上并不需要脚本。例如,原始海报想要类似的内容:
这可以使用此命令行轻松完成:
或者甚至更短:
或者更短,更符合:
或者最后,使用序列:
I know this question is old, but I wanted to throw this answer on here in case someone comes looking for an answer.
Shells like BASH support making directories recursively like this already, so a script isn't really needed. For instance, the original poster wanted something like:
This is easily done with this command line:
Or even a bit shorter:
Or shorter, with more conformity:
Or lastly, using sequences:
getopts 选项只能采用零个或一个参数。您可能想要更改界面以删除 -f 选项,然后迭代其余的非选项参数
所以,
getopts options can only take zero or one argument. You might want to change your interface to remove the -f option, and just iterate over the remaining non-option arguments
So,
如果要为选项指定任意数量的值,可以使用简单的循环来查找它们并将它们填充到数组中。例如,让我们修改 OP 的示例以允许任意数量的 -s 参数:
这采用第一个参数 ($OPTARG) 并将其放入数组 $sub 中。然后它将继续搜索剩余的参数,直到它命中另一个虚线参数或者没有更多的参数需要评估。如果它发现更多不是虚线参数的参数,则会将其添加到 $sub 数组中并增加 $OPTIND 变量。
因此,在OP的示例中,可以运行以下命令:
如果我们将这些行添加到脚本中进行演示:
输出将是:
If you want to specify any number of values for an option, you can use a simple loop to find them and stuff them into an array. For example, let's modify the OP's example to allow any number of -s parameters:
This takes the first argument ($OPTARG) and puts it into the array $sub. Then it will continue searching through the remaining parameters until it either hits another dashed parameter OR there are no more arguments to evaluate. If it finds more parameters that aren't a dashed parameter, it adds it to the $sub array and bumps up the $OPTIND variable.
So in the OP's example, the following could be run:
If we added these lines to the script to demonstrate:
The output would be:
我解决了与您遇到的同样的问题:
而不是:
这样做:
使用空格分隔符,您可以使用基本循环来运行它。
这是代码:
这是示例输出:
I fixed the same problem you had like this:
Instead of:
Do this:
With the space separator you can just run through it with a basic loop.
Here's the code:
Here's a sample output:
实际上有一种方法可以使用
getopts
检索多个参数,但它需要使用getopts
'OPTIND
变量进行一些手动修改。请参阅以下脚本(转载如下): https://gist.github.com/achalddave/290f7fcad89a0d7c3719。可能有一种更简单的方法,但这是我能找到的最快的方法。
There actually is a way to retrieve multiple arguments using
getopts
, but it requires some manual hacking withgetopts
'OPTIND
variable.See the following script (reproduced below): https://gist.github.com/achalddave/290f7fcad89a0d7c3719. There's probably an easier way, but this was the quickest way I could find.
最初的问题涉及 getopts,但还有另一种解决方案可以在没有 getopts 的情况下提供更灵活的功能(这可能有点冗长,但提供了更灵活的命令行界面)。下面是一个示例:
在此示例中,我们循环遍历所有命令行选项,查找与我们接受的命令行标志(例如 -f 或 --foo)相匹配的参数。一旦找到一个标志,我们就会循环遍历每个参数,直到用完参数或遇到另一个标志。这让我们回到了只处理标志的外循环。
通过此设置,以下命令是等效的:
您还可以解析极其混乱的参数集,例如:
要获取输出:
The original question deals with getopts, but there is another solution that provides more flexible functionality without getopts (this is perhaps a bit more verbose, but provides a far more flexible command line interface). Here is an example:
In this example we are looping through all of the command line options looking for parameters that match our accepted command line flags (such as -f or --foo). Once we find a flag, we loop through every parameter until we run out of parameters or encounter another flag. This breaks us back out into our outer loop which only processes flags.
With this setup, the following commands are equivalent:
You can also parse incredibly disorganized parameter sets such as:
To get the output:
以下链接应该是此要求的通用解决方案。
它很容易注入,足够清晰易懂,也最大限度地减少了对原始代码的影响。
使用 getopts (bash) 的多个选项参数
The following link should be a general solution for this requirement.
It's easy to inject and clear enough to understand also minimizes the impact on the original code.
Multiple option arguments using getopts (bash)
由于您没有显示您希望如何构建列表,
所以有点不清楚如何继续,但基本上您需要不断将任何新值附加到适当的变量,即
请注意,在第一次传递时 dir 将为空,并且您将会在
${dirList}
的最终值的起始位置出现一个空格。 (如果你确实需要不包含任何额外空格的代码,无论是前面还是后面,我可以向你展示一个命令,但它会很难理解,而且你似乎在这里不需要它,但让我知道)然后您可以将列表变量包装在 for 循环中以发出所有值,即
最后,将任何未知输入“捕获”到 case 语句被认为是很好的做法,即
我希望这会有所帮助。
As you don't show how you hope to construct your list
it's a little unclear how to proceed, but basically you need to keep appending any new values to the appropriate variable, i.e.
Note that on the first pass dir will be empty, and you'll wind up with a space leading at the from of your final value for
${dirList}
. (If you really need code that doesn't include any extra spaces, front or back, there is a command I can show you, but it will be hard to understand, and it doesn't seem that you'll need it here, but let me know)You can then wrap your list variables in for loops to emit all the values, i.e.
Finally, it is considered good practice to 'trap' any unknown inputs to your case statement, i.e.
I hope this helps.
这是为单个选项传递多个参数的简单方法。
This is a simple way to pass multiple arguments for a single option.