为命令格式化 bash 变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/458972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
format bash variable for command
提问by stew
From my bash shell I would like to call a program n times with a different numbered parameter, which has to be in a fixed format like "%02i"
在我的 bash shell 中,我想使用不同的编号参数调用程序 n 次,该参数必须采用固定格式,例如“%02i”
One way would be:
一种方法是:
for ((i=23; i<42;i++)); do
sh ../myprogram `printf "%02i\n" $i`
done
Is there a way to improve the printf..
part? I believe this might be a performance bottleneck with more files and makes the line less readable than a built-in function (especially when condensed to a one-liner).
有没有办法改进printf..
零件?我相信这可能是一个性能瓶颈,因为有更多的文件,并且使得该行的可读性低于内置函数(尤其是当压缩为单行时)。
回答by Commodore Jaeger
In Bash, printf
is provided by the shell (see the bash(1) manpage, search for "printf"), so you don't even have the (minimal) overhead of fork()
and exec()
to execute a separate command -- unless you run it from within backticks. Bash's built-in printf lets you assign the output to a given variable with the -v
argument; your script fragment could be rewritten as:
在bash中,printf
由外壳提供的(见在bash(1)手册页,搜索的“printf”),所以你甚至不用的(最小的)的开销fork()
,并exec()
执行一个单独的命令-除非你运行它反引号内。Bash 的内置 printf 允许您使用-v
参数将输出分配给给定的变量;您的脚本片段可以重写为:
for ((i=23; i<42;i++)); do
printf -v ii "%02i\n" $i
sh ../myprogram $ii
done
I'm not sure I'd consider that more readable than the original.
我不确定我会认为它比原版更具可读性。
The most resource-intensive part of your script fragment is calling your other shell script; I wouldn't worry about the overhead of calling printf unless further evidence indicates otherwise.
脚本片段中资源最密集的部分是调用其他 shell 脚本;除非另有证据表明,否则我不会担心调用 printf 的开销。
edited to add the difference between backticks and direct execution
编辑以添加反引号和直接执行之间的区别
回答by Johannes Schaub - litb
Your number already has 2 decimal places. Why do you need to use printf then? If i remember correctly (haven't got a shell for testing here), it just pads the number up to 2 decimals when used with those flags. Personally, i like xargs:
您的号码已经有 2 位小数。那你为什么需要使用 printf 呢?如果我没记错的话(这里没有用于测试的外壳),当与这些标志一起使用时,它只会将数字最多填充 2 位小数。就个人而言,我喜欢 xargs:
seq 23 42 | xargs -n1 sh ../myprogram
You can use the -w
argument for seq
, which pads the numbers with zeros if necessary, so they have all the same width.
您可以使用-w
for 参数seq
,如有必要,它将用零填充数字,使它们具有相同的宽度。
It turns out seq
is linux specific. Thanks for Dave in the comments for figuring it out (his answer). Use printf
directly, without a loop:
事实证明seq
是特定于 linux 的。感谢 Dave 在评论中解决这个问题(他的回答)。printf
直接使用,不循环:
printf '%02i\n' {23..42} | xargs -n1 sh ../myprogram
I like to use xargs
, because it allows easily running your commands in parallel up to some limit, can pass more than one number at once and allows other flexible options. Like Dave, i recommend you to drop the sh
from it, and place it into your shell script, as first line instead:
我喜欢使用xargs
,因为它允许轻松地并行运行您的命令直到某个限制,可以一次传递多个数字并允许其他灵活的选项。像 Dave 一样,我建议您将其删除sh
,并将其放入您的 shell 脚本中,作为第一行:
#!/bin/sh
.....
Then just execute your stuff as
然后只需执行你的东西
printf '%02i\n' {23..42} | xargs -n1 ../myprogram
This is more generic, and allows your script also to be called by the exec
C library calls (at least in Linux, that's the case).
这是更通用的,并且允许您的脚本也被exec
C 库调用调用(至少在 Linux 中是这样)。
回答by Dave C
FYI: A completely different solution:
仅供参考:一个完全不同的解决方案:
jot -w "%02i" - 23 42 | xargs -n 1 ../myprogram
This has the performance downside of calling jot(standard since 4.2BSD so all the BSD derivatives have it, but a quick look shows that this basic wonderful tool appears to be lacking from the Linux distributions I looked at). Edit: Linux (at least Red Hat) appears to have a subset of jot's features in a command called seq(thanks to litb's answerfor this info).
这有调用jot的性能缺点(自 4.2BSD 起是标准的,所以所有 BSD 衍生产品都有它,但快速浏览一下,我看到的 Linux 发行版似乎缺少这个基本的好工具)。 编辑:Linux(至少是 Red Hat)在名为seq的命令中似乎具有 jot 功能的一个子集(感谢 litb对此信息的回答)。
This has the benefit of working in non-bash shells as well (unlike what some people think, there is more than one shell in active use and shell-agnostic solutions are generally a good idea).
这也有在非 bash shell 中工作的好处(与某些人认为的不同,有多个 shell 处于活动状态,与 shell 无关的解决方案通常是一个好主意)。
回答by Paul Tomblin
How about
怎么样
for i in {23..42} ; do
sh ../myprogram $i
done
Numbers between 23 and 42 are always going to be in %02i format.
23 到 42 之间的数字始终采用 %02i 格式。
If you absolutely must format, then
如果你绝对必须格式化,那么
for i in {23..42} ; do
printf "%02i\n" | xargs -n1 sh ../myprogram $i
done
Substitutes the overhead of spawning xargs for the overhead of spawning the subshell for the backticks. I have no idea which is more efficient.
用生成 xargs 的开销代替生成反引号的 subshell 的开销。我不知道哪个更有效。
回答by mpoesse
try:
尝试:
seq -w 23 41
This will fillup with leading 0 automatically to needed size
这将自动填充前导 0 到所需的大小
or:
或者:
seq -f "%02g" 1 29
This will format to exact 2 digits.
这将格式化为精确的 2 位数字。
So complete command would be:
所以完整的命令是:
for i in `seq -f "%02g" 23 41`; do
sh ../myprogram $i
done