1. 程式人生 > >awk詳解使用用法

awk詳解使用用法

awk

awk

流編輯器 適合處理有行有列 比較規則的文本

awk 讀入一行,執行一次主輸入循環
#awk ‘BEGIN{} {}END{}‘ 文件名稱
BEGIN{}處理所有文本之前執行 不想執行可以不加BEGIN
{} 主輸入循環
END{} 處理所有文本之後的執行 可選

{}中字符串必須加“” 如果一個字符串不不加引號,會被當作一個變量來處理

Awk讀入一行,執行一次括號裏面的動作
讀入一行,執行一次後面的主輸入循環

#awk ‘{}‘ /etc/passwd
#awk 選項 ‘BEGIN{} {} END{}‘ 文件

print語句如果沒有參數,只簡單輸出每個輸入行

#cat test2

Hello, world
#awk ‘{ print }‘ test2
Hello, world
awk 程序設計模型
awk 程序由所謂的主輸入(main input)循環組成。一個循環稱作一個例程。
awk允許你編寫兩個特殊的例程,他們在任何輸入被讀取前和所有輸入都被讀取後執行。他們是與BEGIN和END規則相關的過程。BEGIN和END過程是可選的。

awk ‘BEGIN {print “hello,World”}’

Hello,World
BEGIN模式不需要等待輸入,它在第一個輸入行讀入之前執行。

BEGIN{} 所有文本內容讀入之前要執行的命令
{} 主輸入循環 用的最多

END{} 所有文本全部讀入完成之後執行的命令

print
不跟任何參數,打印awk讀入的內容
跟參數:
數字 不要加引號
字符串 必須加引號
變量 沒有加引號的字符串

 print  5
 print  a
 print "a"

模式匹配
#cat src1.awk
/[0-9]+/ { print "That is an integer" }
/[A-Za-z]+/ { print "This is a string" }
/^$/ { print "This is a blank line." }

一個特殊的例子:一行文本可以匹配一條或多條規則

#echo 4t | awk -f src1.awk
That is an integer
This is a string

記錄和字段

awk假設它的輸入是有結構的,而不是一串無規則的字符。默認它將每個輸入行作為一條記錄,而將由空格或制表符分隔的單詞作為字段。連續的多個空格和/或制表符被作為一個分隔符。

記錄:以記錄分割符分割的字符串
字段:以字段分割符分割的字符串
字段包括在記錄裏面

默認記錄分隔符:\n
默認字段分隔符:單個或多個空格 \tab 或 當\n不是記錄分隔符的時候\n是字段分隔符

record 記錄
$0 整條記錄
NR 記錄號 number record
FNR F代表文件 將2文件分開記錄行號
RS 輸入記錄分隔符 record separate
ORS 輸出記錄分隔符
$1 第一個字段
$2 第二個字段
$...
NF 字段個數
FS 輸入字段分隔符
OFS 輸出字段分隔符
FILENAME 被處理的文件的名稱
,表示的是默認輸出字段分隔符 默認是空格

#awk ‘BEGIN{FS=":";OFS=":"}{print $1"("$3")"}‘ /etc/passwd

#awk ‘BEGIN{FS= ":";printf("%-25s %-30s\n", "用戶名","uid")}{printf("%-25s %-30s\n",$1,$3)}‘ passwd
用戶名 uid
emon 2
lp 4
sync 5
tcpdump 72
xiaomi 1000

手動指定FS的值:

#awk ‘BEGIN{FS=":|="}{print $1}‘ a FS="冒號或等號"
hello
wenjian
bianji
chakan
sousuo

字段的引用和分離

John Robinson 666-555-1111
awk允許使用字段操作符$來指定字段。$後面可以跟著一個數字或者一個變量。
$1表示第一個字段,$2表示第二個字段,$0表示整個輸入記錄。

#awk ‘{ print $2, $1, $3 }‘ names
Robinson John 666-555-1111

可以使用-F來改變字段分隔符

#awk -F"\t" ‘{ print $2 }‘ names
666-555-1111
#awk -F"\t+" ‘{ print $2 }‘ names
#awk -F"[‘:\t]" ‘{ print $2 }‘ names
任何3個字符之一都可以被解釋為字段分隔符

也可以在腳本中指定域分隔符,通過系統變量FS來改變
BEGIN { FS = "," } # comma-delimited fields
{ print $1 "-" $2 }

使用匹配規則

/MA/ { print $1 ", " $6 }

為了避免假警報,可以使用更精確的匹配 ~是匹配的意思
$5 ~ /MA/ { print $1 ", " $6 }
還可以使用!來反轉這個規則的意義 !~就是不匹配的意思
$5 !~ /MA/ { print $1 ", " $6 }

表達式:

常量
分成兩種:字符串型和數字型
字符串型在表達式中必須用引號括起來
字符串中可以使用轉義序列,常用的轉義序列有:
\n 換行 \t 水平制表符 \r 回車

變量

x=1
x是變量的名字 =是一個賦值操作符 1是一個數字常量
註意:變量區分大小寫,所以x 和X(大寫)表示不同的變量
變量名只能由數字字母下劃線組成,而且不能以數字開頭
變量使用不區分類型,使用前不必初始化
z = "Hello"
z = "Hello" "World"
z = $1
以上幾種都是合法的

常用算術操作符:

  • Addition 加
  • Subtraction 減
  • Multiplication awk ‘{print (5+3)*8}‘ passwd 乘
    / Division awk ‘{print (5+3)/8}‘ passwd 除以
    % Modulo 取模 = 取余

$RANDOM 隨機取值

echo $[$RANDOM%5] shell 裏邊用的 第一個$是shell裏邊的取值 第二個是隨機取值它是一個變量

x=1 給x賦值
y=x+1 計算x的值,使它加1,並將結果賦給變量y。
print y 打印y的值。
我們可以將這3個語句減少為兩個:
x=1
print x+1
2

常用賦值操作符

++ Add 1 to variable.
-- Subtract 1 from variable.
+= Assign result of addition.
-= Assign result of subtraction.
*= Assign result of multiplication.
/= Assign result of division.
%= Assign result of modulo.
^= Assign result of exponentiation.(取冪)
x++ ++x 都是 x=x+1 x++ ++x 區別在++ x 先加一在算x的值 x++ 先算x值在加
比如awk ‘BEGIN{x=1;print ++x}‘ 這樣值是2
awk ‘BEGIN{x=1;print x++}‘ 這樣值是1
for (x=1;x<=5;x++) 在for循環中沒有區別

x-- --x 都是 x=x-1
x^ 這意思是 x的x次方 x^3 這就是x的3次方

計算文件中空行的數目
#awk ‘/^$/{x++}END{print x}‘ b
8

例如

計算學生的平均成績
mona 70 77 85 83 70 89
john 85 92 78 94 88 91
andrea 89 90 85 94 90 95
jasper 84 88 80 92 84 82
dunce 64 80 60 60 61 62
ellis 90 98 89 96 96 92

#awk ‘{total=$2+$3+$4+$5;print $1,total/4}‘ b
姓名 0
tom 60
jim 35
lilei 67.75

系統變量:

$0 整條記錄
$1 第一個字段
FS 定義字段分隔符,默認為一個空格
OFS 輸出的字段分隔符,默認為一個空格
RS 記錄分隔符,默認為一個換行符
ORS 輸出的記錄分隔符,默認為一個換行符
NR 行數
FNR 行數,多文件操作時會重新排序
NF 字段的個數
FILENAME 文件名

關系操作符和布爾操作符

關系操作符

< Less than

Greater than
<= Less than or equal to
= Greater than or equal to
== Equal to
!= Not equal to
~ Matches 匹配
!~ Does not match 不匹配
NF == 5 NF(每個輸入記錄的字段數)的值和5相比較,如果結果為真,那
麽就進行相應的處理,否則不進行處理。
$5 ~ /MA/ {print $1 “,”$6}
註意:關系操作符==和賦值操作符=是不同的
awk與裏邊只有真和假 0真1假 shell裏邊正好相反 真的就執行假的就不執行

獲取文件夾中文件總大小

ll | awk ‘{sum=sum+$5}END{print sum}‘
4521807078

格式化打印
printf ( format-expression [, arguments] )
c ASCII 字符
d 十進制整數
f 浮點格式
s 字符串
x 無符號十六進制

常用舉例:

語法 %-width.precision format-specifier
printf(" %d \t %s \n ", $5 , $8 )
printf("|%10s|\n", "hello") 右對齊
printf("|%-10s|\n", "hello") 左對齊
printf("%.f\n", 5, 3, myvar) 寬度5 精度3 打印myvar

循環

while 循環
while (condition)
action

例:
i = 1
while ( i <= 4 ) {
print $i
++i
}

do 循環 先
do
action
while (condition)

例:
BEGIN {
do {
++x
print x
} while ( x <= 4 )
}

for 循環
for ( set_counter ; test_counter ; increment_counter )
action
for(變量初始化;變量變化範圍-條件;增幅)

for(num=1;num<=9;num++) print num

num=1 //初始化
num<9條件成功 //判斷
num=1 //執行循環體
打印1 //執行循環體

num=2 //num++
條件成功 //判斷
2 //執行循化 體

先執行循環體在執行num++
一直循環下去,直到條件不成功,退出循環

例如:
從第一個字段到最後一個字段
for ( i = 1; i <= NF; i++ )
print $i

從最後一個字段到第一個字段
for ( i = NF; i >= 1; i-- )
print $i

用for實現求平均值
total = 0
for (i = 2; i <= NF; ++i)
#total = $2 + $3 + $4 + $5 + $6
#avg = total / 5
或者用下方在這個
total += $i
avg = total / (NF - 1)

awk重定向
#awk -F : ‘{print $1 >> "/tmp/awktest"}‘ /etc/passwd

awk管道
#awk -F : ‘{print $1 | "sort"}‘ /etc/passwd

awk詳解使用用法