简体   繁体   English

如何在bash中格式化数字(可能使用printf格式化)?

[英]How to format a number in bash, possibly with printf?

This so simple script is failing : 这个简单的脚本失败了:

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

with

3: printf: Illegal option -v

WHY !!! 为什么! (ubuntu 14.04) (Ubuntu 14.04)

You're probably using a version of Bash not supporting -v option yet. 您可能正在使用不支持-v选项的Bash版本。 Try running bash --version . 尝试运行bash --version It should be 3.1 or newer. 它应该是3.1或更高版本。

Also, make sure you do run your script with bash. 另外,请确保您确实使用bash运行脚本。 Try explicitly calling bash script.sh . 尝试显式调用bash script.sh

Per @Joe, this appears to be a duplicate of Whats the difference between running a shell script as ./script.sh and sh script.sh . 对于@Joe,这似乎是Whats和Shell脚本作为./script.sh和sh script.sh运行之间的区别的重复。

Per @Telemachus, Debian and its derivatives use dash as their default shell. 对于@ Telemachus,Debian及其派生工具使用破折号作为默认外壳。 See http://wiki.ubuntu.com/DashAsBinSh for more information. 有关更多信息,请参见http://wiki.ubuntu.com/DashAsBinSh

Here's what I see on an Ubuntu system: 这是我在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*

That explains why I was not able to reproduce the issue on Mac OS X 10.8.5. 这就解释了为什么我无法在Mac OS X 10.8.5上重现该问题。 I did reproduce it on Ubuntu by invoking the script with sh instead of bash . 确实在Ubuntu上通过使用sh而不是bash调用脚本来重现它。

I'm leaving the rest of my answer in place since it demonstrates some steps you might take to troubleshoot the problem. 我将其余答案保留在原处,因为它演示了您可能需要采取的一些步骤来解决问题。

Can you check your version of bash? 您可以检查您的bash版本吗?

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

Does this even work? 这还行吗?

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

Check the type of the name printf ? 检查名称printf的类型?

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

Check the builtin help for the printf builtin? 检查内置帮助以获取内置的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.

Has the builtin printf been replaced by a definition from somewhere else? 内置的printf已被其他地方的定义所替代? Here's a function I use for checking the definition of names in the 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
}

Here's the output when I run this in a fresh shell: 这是我在新的shell中运行此命令时的输出:

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

But if I redefine printf , it will show the definition: 但是,如果我重新定义printf ,它将显示定义:

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

I am curious to hear what's really going on here!!! 我很好奇听到这里到底发生了什么!!!

I like the other answer's suggestion to try invoking the script explicitly w/ bash: 我喜欢其他答案的建议,尝试使用bash显式调用脚本:

$ bash myscript.sh

Here's what I see on an Ubuntu server: 这是我在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

You're running the script as an argument to /bin/sh , like this: 您正在将脚本作为/bin/sh的参数运行,如下所示:

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

which ignores the #! 忽略#! line. 线。 Run it as: 运行为:

$ ./script.sh
00001

instead. 代替。

As other answers tell you that older BASH version versions don't support printf -v but here is what you can do that in older BASH to set fn : 正如其他答案告诉您的那样,较早的BASH版本不支持printf -v但是您可以在较早的BASH中执行以下操作来设置fn

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM