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

时间:2012-11-27 09:52:32

标签: 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中显然不支持
  • 函数本身会生成值,因此无法接收完整的文件名作为参数

1 个答案:

答案 0 :(得分:3)

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

$ printf "%.s%s\n" "Bonjour" "Hello"
Hello
$ printf "%s%.s\n" "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实践。