printf和echo结婚种种情况

一、Printf简介

Printf的功能是格式和打印数据(format and print data),即把标准输出的内容,通过printf命令转换成另类的格式输出。


二、echo与printf 异曲同工之妙

echo命令可以实现的功能,printf命令同样可以实现,两者之间的微妙之处在于printf+awk可以实现更强大的功能,对于echo可以说printf更胜一筹。


1)标准输出

[root@keepalived_master scripts]# echo "hello world"

hello world

[root@keepalived_master scripts]# printf "hello world\n"

hello world

注:printf语句若不加\n,默认输出不换行。


2)换行输出

[root@keepalived_master scripts]# echo -e "hello \nworld"

hello

world


[root@keepalived_master scripts]# printf "hello \nworld\n"

hello

world

注:echo语句使用-e参数,使其\n具有特殊意义,实现字符换行输出。


3)不换行输出

[root@keepalived_master scripts]# echo -n "hello world"

hello world[root@keepalived_master scripts]#


[root@keepalived_master scripts]# printf "hello world"

hello world[root@keepalived_master scripts]#

注:echo语句默认是换行输出,使用-n选项可用实现不换行输出。


4)字符与字符间距

[root@keepalived_master scripts]# echo -e "hello \tworld"

hello world

[root@keepalived_master scripts]# printf "hello \tworld\n"

hello world

注:通过\t参数,可用实现字符之间有一个tab建的距离。


5)判断上一条命令执行的结果是否正确

[root@keepalived_master scripts]# ll

total 8

-rw-r--r-- 1 root root 1876 Sep 12 13:00 mac.txt

-rw-r--r-- 1 root root 594 Sep 12 13:08 user_mac_forward.sh

[root@keepalived_master scripts]# echo $?

0


[root@keepalived_master scripts]# ll

total 8

-rw-r--r-- 1 root root 1876 Sep 12 13:00 mac.txt

-rw-r--r-- 1 root root 594 Sep 12 13:08 user_mac_forward.sh

[root@keepalived_master scripts]# printf "$? \n"

0

注:通过$?判断上一条命令执行后返回的结果,0:正确,1-255:错误。


6)输出变量的值

[root@keepalived_master scripts]# hello=world

[root@keepalived_master scripts]# echo $hello

World


[root@keepalived_master scripts]# hello=very

[root@keepalived_master scripts]# printf "$hello \n"

very


7)让字符串带颜色输出

提示:为了让结果更明显,以shell脚本的方式批量执行。

[root@keepalived_master scripts]# cat echo_color.sh

1
2
3
4
5
6
7
8
#!/bin/bash
echo -e "\033[31mplease input one number: \033[0m"  -->红色
echo -e "\033[32mplease input one number: \033[0m"-->绿色
echo -e "\033[33mplease input one number: \033[0m"-->***
echo -e "\033[34mplease input one number: \033[0m"-->蓝色
echo -e "\033[35mplease input one number: \033[0m"-->粉色
echo -e "\033[36mplease input one number: \033[0m"-->青色
echo -e "\033[37mplease input one number: \037[0m"-->白色


160303797.png

[root@keepalived_master scripts]# cat printf_color.sh

1
2
3
4
5
6
7
8
#!/bin/bash
printf "\033[31mplease input one number: \033[0m\n"
printf "\033[32mplease input one number: \033[0m\n"
printf "\033[33mplease input one number: \033[0m\n"
printf "\033[34mplease input one number: \033[0m\n"
printf "\033[35mplease input one number: \033[0m\n"
printf "\033[36mplease input one number: \033[0m\n"
printf "\033[37mplease input one number: \033[0m\n"


160501315.png

注:让字符输出时带有颜色,可以让结果更加明显;在编写shell脚本时,经常用到此方法,建议大家掌握。


三、printf命令对比echo拥有的特性

1)从命令行引用传值

[root@keepalived_master scripts]# printf "%s %s %s %s\n" Are you happy today

Are you happy today

注:Are you happy today分别被%s->Are %s->you %s->happy %s->today引用,终端输出的结果即为Are you happy today



2)格式化输出

[root@keepalived_master scripts]# printf "%s %10s %10s %10s\n" Are you happy today  

Are you happy today

注:%s字符之间分隔的空间,%10s表示分隔10个字符的间距。


3)使用前导零扩展%d

[luofeng@CNC_BJ_009_188 ~]$ for ip in `seq 00 20`;do printf "%d \n" $ip;done

0

1

2

3

4

5

6

----省略----

注:上述命令使用for循环00-20的数字,因为%d默认精度为1printf打印在终端的结果为0-20

[luofeng@CNC_BJ_009_188 ~]$ for ip in `seq 00 99`;do printf "%02d \n" $ip;done

00

01

02

03

04

05

06

07

----省略-----

注:%02d使其默认的精度从1变为2printf打印的结果便为我们看到的00-20,在数字1前置0.

d:接受整数值并将它转换为有符号的十进制符号表示法。精度指定显示的最小数字位数。如果值转换后可以用更少的位数来表示,将使用前导零扩展。缺省精度是 1


四、Awk示例分享

注:首先分享一些工作中常用awk的实例

160528886.png

1)通过逻辑运算符“&&”与“||”,过滤文本内容

[root@keepalived_master ~]# awk '$1=="root" && $3==0' test.txt

root  x 0 0  /root   /bin/bash

注:过滤的内容中包含字符串,需要用双引号“”。

$1...$n:表示第文本内容的第几列,其中$1==root$2==x$3==0.....$n==$n

&&:表示逻辑与,即满足条件第一列为root,第三列为0的行才会被显示



[root@keepalived_master ~]# awk '$1=="sync" || $5=="/root"' test.txt

root  x 0 0  /root   /bin/bash

sync  x 5 0  /sbin   /bin/sync

operator x 11 0  /root   /sbin/nologin

注:只要满足$1==sync”或者$5==/root”其中的一个过滤条件,文本内容标准输出至终端。

||:表示逻辑或,即满足过滤条件任意一个,文本内容标准输出。


2)通过比较运算符!===>=,<=><过滤文本内容

160553591.png

注:$3为用户的UID,满足过滤条件‘$3>500’的行,标准输出到终端。

160804262.png

注:$3为用户的UID,满足过滤条件‘$3>500’的行,标准输出到终端。


160844326.png

注:当满足条件$4 <= 4时,有8行内容标准输出;然后运用逻辑与&&过滤$4 != 0的行,从图中可以看出结果,3行满足过滤条件。


3)Awk常用内置变量

$0

当前记录,变量存放文件整行的内容。

$1~$n

记录文件当前行的第n列,字段间由FS分隔。

NF

当前记录中的字段个数,就是有多少列

NR

已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中

FS

输入字段分隔符默认是空格或Tab

OFS

输出字段分隔符, 默认也是空格


实例1

[root@keepalived_master ~]# awk '$1 ~ /root/{print $0}' test.txt

root  x 0 0  /root   /bin/bash


[root@keepalived_master ~]# awk '$1 ~ /root/{print $1}' test.txt

root

注:通过终端显示的结果可以看出,满足过滤条件$1 ~ /root$0输出文件整行的内容,而$1输出整行中第一列。

实例2:

[root@keepalived_master ~]# awk 'NR==2 {print $0}' test.txt

bin  x 1 1  /bin   /sbin/nologin


[root@keepalived_master ~]# awk '$3 >=10 && NR==20 {print $0}' test.txt

ntp  x 38 38  /etc/ntp   /sbin/nologin


[root@keepalived_master ~]# cat -n test.txt | grep 20

20 ntp x 38 38  /etc/ntp   /sbin/nologin

注:NR记录当前文件中的行号,其中bin用户的行号为2,满足过滤条件NR==2标准输出,ntp用户的UID大于10,同时满足过滤条件Nr==20cat -n test.txt | grep 20证实了这一结论。


实例3:

160946252.png


注:通过OFS=\t””指定了文件中列与列之间的距离,\t表示4个字符的距离,可以看出两条命令执行的结果有差异。


实例4

1
2
3
4
[root@keepalived_master ~]# netstat -n | awk '/^tcp/{++S[$NF]}END{for(key in S) print key,"\t",S[key]}'
TIME_WAIT 243
SYN_SENT 1
ESTABLISHED 58

注:此条命令在工作中常用,查看Linux服务器活动链接状态,根据命令的返回结果,可以推论出当前服务器负载情况。

提示:

分析整条命令的含义:首先通过/^tcp/过滤出TCP的连接状态,然后定义S[]数组;$NF表示最后一列,++S[$NF]表示数组中$NF的值+1END表示在最后阶段要执行的命令,通过for循环遍历整个数组;最后print打印数组的键和值


提示:对于$NF还有不太明白朋友,可以看看下列实例:

161631488.png

五、AWK+Printf完美结合

1)分享Web站点访问日志,以脚本的形式:

脚本1

[root@keepalived_master ~]# cat analyze_web_log.sh

1
2
3
4
5
6
#!/bin/bash
# create author of cfwl
# create date of 2013-10-12
# scripts function analyze web site access log
# print web site log and sort
cat /application/nginx-1.2.9/logs/access.log | awk '{print $1,$4,$9,$19,$22}' |sort | uniq -c | sort -nr


脚本2

[root@keepalived_master ~]# cat funtion_analyze_web_log.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
# create author of cfwl
# create date of 2013-10-12
# scripts function analyze web site access log
sh analyze_web_log.sh|
awk '
BEGIN{
 print "----------------------------------------------------------------------------";
 print "| Total | Access_IP |  Access_Date  | State | Access_browser |";
 print "----------------------------------------------------------------------------";
}
{
 printf "| %-5s | %-14s | %-11s | %-5s | %-15s |\n",$1,$2,$3,$4,$5,$6;
}
END{
 print "----------------------------------------------------------------------------";
}'


注:执行结果

161038504.png

提示:在利用rsync备份数据时,可以通过printf+awk格式化比较两端目录的大小是否一致,此脚本仅提供参考,看大家如何利用,希望此篇文档能够帮助到大家。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章