bash printf:忽略参数还是按索引访问



我有一个bash函数,它获取值(使用curl和cut)并从中创建文件名。现在我想支持第二个命名方案,它需要一组不同的参数。

示例:

#!/bin/bash
TEMPLATE="%02i. %s.txt"
foo() {
a="Imagine these to"
b="be set dynamically"
c="42"
filename="$(printf "$TEMPLATE" "$c" "$a")"
# second: filename="$a - $b.txt"
# or:     filename="$(printf "%s - %s.txt" "$a" "$b")"
echo "$filename"
# generate file
}
# actual script loops over:
foo

其中一个值是一个数字,如果需要,应该用前导零填充,因此在当前实现中为printf

有没有一种方法可以通过在全局范围内设置不同的模板来实现这一点?这将要求模板可以通过索引访问参数,或者至少跳过其中的一些参数。

如果没有,我的替代方案是什么?模板由命令行参数选择,初始化后不会更改。

什么不起作用:

  • bash手册页建议不可能输出零长度(跳过值)
  • C的printf手册页提到了一个"%m$"构造,bash显然不支持这个构造
  • 函数本身会生成值,因此无法接收完整的文件名作为参数

如果需要跳过参数,可以使用%.s。示例:

$ printf "%.s%sn" "Bonjour" "Hello"
Hello
$ printf "%s%.sn" "Bonjour" "Hello"
Bonjour

AFAIK,您不能通过索引访问参数。

如果您需要将格式化后的字符串存储在变量中,请不要像中那样使用子shell

$ variable=$(printf "%.s%s" "Bonjour" "Hello")
$ echo "$variable"
Hello

相反,将-v选项用于printf(键入help printf以获得详细信息),如中所示

$ printf -v variable "%.s%s" "Bonjour" "Hello"
$ echo "$variable"
Hello

此外,如果您的模板可以来自用户输入,我建议您在它之前添加--(这是为了结束命令的选项,以防用户想要用破折号启动模板)。因此,我将取代你的线

filename="$(printf "$TEMPLATE" "$c" "$a")"

带有

printf -v filename -- "$TEMPLATE" "$c" "$a"

最后,使用大写的变量名被认为是糟糕的bash做法。

相关内容

  • 没有找到相关文章

最新更新