骏马金龙 (博客已搬家:www.junmajinlong.com)

网名骏马金龙,钟情于IT世界里的各种原理和实现机制,强迫症重症患者。爱研究、爱翻译、爱分享。特借此一亩三分田记录自己成长点滴!!!

shell脚本--echo和printf打印输出

bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html


注:本文关于引号等特殊符号的处理仅仅只是几个例子,想要彻底搞明白shell对特殊符号的解析,见另一篇文章shell解析命令行的过程

1.2.1 echo引号和感叹号问题

关于echo的用法,注意点就是单引号和双引号的特殊情况。

另外,在bash环境下,感叹号只能通过单引号包围来输出,因为此时感叹号表示引用历史命令,除非设置"set +H"关闭历史命令的引用。而在shell脚本中不会出现这类问题。

以打印“Hello World!”为例。

[root@xuexi tmp]# echo Hello World!

Hello World!

[root@xuexi tmp]# echo 'Hello World!'

Hello World!

[root@xuexi tmp]# echo "Hello World!"   #双引号不能打印感叹号

-bash: !": event not found

[root@xuexi tmp]# echo Hello World!;echo 'Hello World!'  

-bash: !: event not found

[root@xuexi tmp]# echo 'Hello World!';echo Hello World!  #感叹号可以在最结尾

Hello World!

Hello World!

从上面几个实验发现,在bash环境下,要输出感叹号必须使用单引号。这是因为默认情况下开启了使用感叹号引用内存中的历史命令的设置,可以使用set +H关闭该设置,这时可以使用感叹号输出。

[root@xuexi tmp]# set +H

[root@xuexi tmp]# echo "Hello World!"

Hello World!

或者使用多对引号分别包围echo的参数,其中感叹号使用单引号包围,如下。

[root@xuexi ~]# echo "Don't use rm -rf command"'!'
Don't use rm -rf command!

如果echo不加任何引号,很显然不能输出分号“;”,因为分号会被shell解析为命令连接符号。

[root@xuexi tmp]# echo Hello World;
Hello World  # 分号作为断行符号被忽略了

但只加单引号又不能扩展变量,使用双引号又不好输出感叹号,所以echo命令克服各种疑难杂症的方法是对特殊符号分开引用。

[root@xuexi ~]# str=hello

[root@xuexi ~]# echo "$str"'!' "world"
hello! world

1.2.2 echo中的转义

echo -e识别转义和特殊意义的符号,如换行符、n、制表符\t、转义符\等。

[root@xuexi tmp]# echo 'Hello World!\n';echo "Hello World"!  

Hello World!\n

Hello World!

[root@xuexi tmp]# echo -e 'Hello World!\n';echo "Hello World"!

Hello World!

            #换行

Hello World!

1.2.3 echo默认的分行处理

不加-n的默认情况下echo会在每行行尾加上换行符号,使用echo -n取消分行输出。

[root@xuexi tmp]# echo 'Hello World!'>abc.sh  #输入完就加了分行符号

[root@xuexi tmp]# echo 'Hello World!'>>abc.sh

[root@xuexi tmp]# cat abc.sh

Hello World!

Hello World!

[root@xuexi tmp]# echo -n 'Hello World!'>abc.sh   #取消了分行符号

[root@xuexi tmp]# echo 'Hello World!'>>abc.sh 

[root@xuexi tmp]# cat abc.sh

Hello World!Hello World!

1.2.4 echo的颜色输出

echo可以控制字体颜色和背景颜色输出。

常见的字体颜色:重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,紫色=35,天蓝色=36,白色=37。

常见的背景颜色:重置=0,黑色=40,红色=41,绿色=42,黄色=43,蓝色=44,紫色=45,天蓝色=46,白色=47。

字体控制选项:1表示高亮,4表示下划线,5表示闪烁等。

因为需要使用特殊符号,所以需要配合-e选项来识别特殊符号。

[root@xuexi tmp]# echo -e "\e[1;41m Red Bcakground \e[0m"

[root@xuexi tmp]# echo -e "\e[1;31m Red Bcakground \e[0m" 

颜色控制和字体控制选项的定义顺序无所谓,只要被定义出来,shell都能识别。建议定义了颜色后同时定义关闭颜色,否则颜色会继续影响bash环境的颜色。

另外,任意一个\e可以使用\033替换。如:

[root@xuexi tmp]# echo -e "\033[1;41m Red Bcakground \033[0m"

[root@xuexi tmp]# echo -e "\e[1;31m Red Bcakground \033[0m" 

1.2.5 printf

使用printf可以输出更规则更格式化的结果。它引用于C语言的printf命令,但是有些许区别。

使用printf可以指定字符串的宽度、实现左对齐(使用减符号-)、右对齐(默认的)、格式化小数输出等。

使用printf最需要注意的两点是:

(1)printf默认不在结尾加换行符,它不像echo一样,所以要手动加“\n”换号;

(2)printf只是格式化输出,不会改变任何结果,所以在格式化浮点数的输出时,浮点数结果是不变的,仅仅只是改变了显示的结果。

[root@xuexi tmp]# cat >abc.sh<<eof  # 将下面的内容覆盖到abc.sh脚本中
> #!/bin/bash
> #文件名:abc.sh
> printf "%-5s %-10s %-4s\n" No Name Mark     # 三个%分别对应后面的三个参数
> printf "%-5s %-10s %-4.2f\n" 1 Sarath 80.34 # 减号“-”表示左对齐
> printf "%-5s %-10s %-4.2f\n" 2 James 90.998 # 5s表示第一个参数占用5个字符
> printf "%-5s %-10s %-4.2f\n" 3 Jeff 77.564
> eof
[root@xuexi tmp]# sh abc.sh  # 执行结果:左对齐,取小数点后两位
No    Name       Mark
1     Sarath     80.34
2     James      91.00
3     Jeff       77.56
[root@xuexi tmp]# sed -i s#'-'##g abc.sh  # 将减号“-”去掉,将右对齐

[root@xuexi tmp]# sh abc.sh 
   No       Name Mark
    1     Sarath 80.34
    2      James 91.00
    3       Jeff 77.56

printf中还可以加入分行符、制表符等符号。

[root@xuexi tmp]# vim abc.sh   #修改abc.sh将其改为如下格式
#!/bin/bash
#文件名:abc.sh
printf "%-s\t %-s\t %s\n" No Name Mark printf "%-s\t %-s\t %4.2f\n" 1 Sarath 80.34 printf "%-s\t %-s\t %4.2f\n" 2 James 90.998 printf "%-s\t %-s\t %4.2f\n" 3 Jeff 77.564
[root@xuexi tmp]# sh abc.sh  # 出现制表符
No       Name    Mark
1        Sarath  80.34
2        James   91.00
3        Jeff    77.56

printf还有一个常见的i格式,表示对整型格式化占用几个整数,前面示例中的s表示对字符格式化。

posted @ 2016-09-28 08:52  骏马金龙  阅读(38004)  评论(1编辑  收藏