如何使用printf格式化bash中的数字?

时间:2014-06-09 13:17:13

标签: bash printf

这么简单的脚本失败了:

#!/bin/bash
n=1
printf -v fn "%05d" $n
echo $fn

3: printf: Illegal option -v

为什么!!! (ubuntu 14.04)

4 个答案:

答案 0 :(得分:2)

您可能还在使用不支持-v选项的Bash版本。尝试运行bash --version。它应该是3.1或更新。

另外,请确保使用bash运行脚本。尝试明确调用bash script.sh

答案 1 :(得分:2)

Per @Joe,这似乎与Whats the difference between running a shell script as ./script.sh and sh script.sh重复。

Per @Telemachus,Debian及其衍生品使用dash作为默认shell。有关详细信息,请参阅http://wiki.ubuntu.com/DashAsBinSh

这是我在Ubuntu系统上看到的内容:

$ ls -lF `which sh`
lrwxrwxrwx 1 root root 4 Aug 15  2012 /bin/sh -> dash*
$ ls -lF `which bash`
-rwxr-xr-x 1 root root 959168 Mar 30  2013 /bin/bash*

这解释了为什么我无法在Mac OS X 10.8.5上重现该问题。我通过使用sh而不是bash调用脚本, 在Ubuntu上重现它。

我将剩下的答案留在原处,因为它展示了您可能采取的一些步骤来解决问题。

你能查看你的bash版本吗?

$ bash --version
bash --version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin12)

这甚至有用吗?

#!/bin/bash
n=1
printf -v fn "%05d" $n
echo $fn

检查名称printf的类型?

$ type printf
printf is a shell builtin
$ function printf { echo "giggle" ; }
giggle
$ type printf
printf is a function
printf () 
{ 
    echo "giggle"
}
giggle
$ 

检查printf内置的内置帮助?

$ help printf
help printf

printf: printf [-v var] format [arguments]
    printf formats and prints ARGUMENTS under control of the FORMAT. FORMAT
    is a character string which contains three types of objects: plain
    characters, which are simply copied to standard output, character escape
    sequences which are converted and copied to the standard output, and
    format specifications, each of which causes printing of the next successive
    argument.  In addition to the standard printf(1) formats, %b means to
    expand backslash escape sequences in the corresponding argument, and %q
    means to quote the argument in a way that can be reused as shell input.
    If the -v option is supplied, the output is placed into the value of the
    shell variable VAR rather than being sent to the standard output.

内置printf是否已被其他地方的定义所取代?这是我用来检查shell中名称定义的函数:

list () 
{ 
    if [[ 0 == $# ]]; then
        Log "";
        Log "FUNCTIONS:";
        Log "----------";
        declare -F;
        Log "";
        Log "EXPORTS:";
        Log "--------";
        export -p;
        Log "";
        Log "PRINTENV:";
        Log "--------";
        printenv;
    else
        while [[ ! -z "$1" ]]; do
            local name="$1";
            shift;
            if ! alias "${name}" 2> /dev/null; then
                if ! declare -f "${name}"; then
                    if ! help "${name}" 2> /dev/null; then
                        if ! which "${name}"; then
                            Log "Not found: '${name}'";
                        fi;
                    fi;
                fi;
            fi;
        done;
    fi
}

这是我在新shell中运行时的输出:

$ list printf
printf: printf [-v var] format [arguments]
    printf formats and prints ARGUMENTS under control of the FORMAT. FORMAT
    [… snip …]

但如果我重新定义printf,它将显示定义:

$ function printf { echo "kibble" ; }
kibble
$ printf
kibble
kibble
$ list printf
printf () 
{ 
    echo "kibble"
}
kibble
$ 

我很想知道这里到底发生了什么!!!

我喜欢其他答案的建议,试着用bash明确地调用脚本:

$ bash myscript.sh

这是我在Ubuntu服务器上看到的内容:

$ uname -a
Linux rack 3.11.0-17-generic #31-Ubuntu SMP Mon Feb 3 21:52:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ cat > dme.sh
#!/bin/bash
n=1
printf -v fn "%05d" $n
echo $fn
$ chmod +x ./dme.sh
$ ./dme.sh
00001
$ bash dme.sh
00001
$ sh dme.sh
dme.sh: 3: printf: Illegal option -v

答案 2 :(得分:2)

您将脚本作为/bin/sh的参数运行,如下所示:

$ sh script.sh 
script.sh: 3: printf: Illegal option -v

忽略#!行。运行方式为:

$ ./script.sh
00001

代替。

答案 3 :(得分:1)

正如其他答案告诉您旧的BASH版本不支持printf -v但是您可以在旧版BASH中执行此操作来设置fn

#!/bin/bash
n=1
fn=$(printf "%05d" "$n")
echo "$fn"