print+awk

一、Printf簡介

Printf的功能是格式和打印數據(format and print data),即把標準輸出的內容,通過printf命令轉換成另類的格式輸出。


二、echoprintf 異曲同工之妙

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

#!/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

#!/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

#!/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

#!/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


原文鏈接:http://cfwlxf.blog.51cto.com/3966339/1309242


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