如何在bash中格式化数字(可能使用printf格式化)? [英] How to format a number in bash, possibly with printf?

查看:64
本文介绍了如何在bash中格式化数字(可能使用printf格式化)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个简单的脚本失败了:

 #!/bin/bashn = 1printf -v fn%05d" $ n回声$ fn 

使用

  3:printf:非法选项-v 

为什么!(ubuntu 14.04)

解决方案

每@Joe,这似乎是 http://wiki.ubuntu.com/DashAsBinSh .

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

  $ ls -lF`sh`lrwxrwxrwx 1根根2012年8月15日/bin/sh->短跑*$ ls -lF`which bash`-rwxr-xr-x 1根目录959168 2013年3月30日/bin/bash * 

这说明了为什么我无法在Mac OS X 10.8.5上重现该问题.我在Ubuntu上通过使用 sh 而不是 bash 调用脚本来重现该脚本.

我将其余答案留在原处,因为它表明了您可能需要采取的一些步骤来解决问题.

可以检查您的bash版本吗?

  $ bash --versionbash --versionGNU bash版本3.2.48(1)-发行版(x86_64-apple-darwin12) 

这还行吗?

 #!/bin/bashn = 1printf -v fn%05d" $ n回声$ fn 

检查名称的类型 printf ?

  $类型printfprintf是一个内置的shell$函数printf {echo"giggle";}傻笑$ type printfprintf是一个函数printf(){回声咯咯地笑"}傻笑$ 

是否检查内置帮助以获取 printf 内置帮助?

  $ help printf帮助printfprintf:printf [-v var]格式[参数]printf在FORMAT的控制下格式化并打印ARGUMENTS.格式是包含三种类型的对象的字符串:普通字符,只需将其复制到标准输出即可,字符转义被转换并复制到标准输出的序列,以及格式规范,每个规范都会导致下一个连续的打印争论.除了标准的printf(1)格式,%b表示在相应的参数中扩展反斜杠转义序列,然后%q表示以一种可以作为shell输入重用的方式引用该参数.如果提供了-v选项,则将输出放置在shell变量VAR而不是发送到标准输出. 

是否已将内置的 printf 替换为其他地方的定义?这是我用来检查外壳程序中名称定义的函数:

 列表(){如果[[0 == $#]];然后日志 "";记录功能:";日志 " -  -  -  -  - ";声明-F;日志 "";记录"EXPORTS:";日志 " -  -  -  - ";出口-p;日志 "";记录"PRINTENV:";日志 " -  -  -  - ";printenv;别的尽管 [[ !-z"$ 1"]];做本地名称="$ 1";转移;如果 !别名"$ {name}" 2>/dev/null;然后如果 !声明-f"$ {name}";然后如果 !帮助"$ {name}" 2>/dev/null;然后如果 !其中"$ {name}";然后日志未找到:'$ {name}'";fi;fi;fi;fi;完毕;科幻} 

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

  $ list printfprintf:printf [-v var]格式[参数]printf在FORMAT的控制下格式化并打印ARGUMENTS.格式[…剪断…] 

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

  $函数printf {echo"kibble";}粗磨$ printf粗磨粗磨$ list printfprintf(){回声粗磨"}粗磨$ 

我很好奇听到这里到底发生了什么!!

我喜欢其他答案的建议,尝试使用bash显式调用脚本:

  $ bash myscript.sh 

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

  $ uname -aLinux 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$猫>dme.sh#!/bin/bashn = 1printf -v fn%05d" $ n回声$ fn$ chmod + x ./dme.sh$ ./dme.sh00001$ bash dme.sh00001$ sh dme.shdme.sh:3:printf:非法选项-v 

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)

解决方案

Per @Joe, this appears to be a duplicate of Whats the difference between running a shell script as ./script.sh and sh script.sh.

Per @Telemachus, Debian and its derivatives use dash as their default shell. See http://wiki.ubuntu.com/DashAsBinSh for more information.

Here's what I see on an Ubuntu system:

$ 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. I did reproduce it on Ubuntu by invoking the script with sh instead of 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 --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?

$ 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?

$ 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? 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:

$ 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:

$ 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 myscript.sh

Here's what I see on an Ubuntu server:

$ 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

这篇关于如何在bash中格式化数字(可能使用printf格式化)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆