linux中gawk用法,Linux - gawk 命令
gawk 是 awk 的 GUN 版
===========================================
是一種《模式掃描和處理》語言。它搜索一個或多個文件,查看這些文件中是否存在匹配指定模式的記錄。發現匹配后,通過執行動作來處理那一行。
語法:
gawk 參數 命令 待處理文件列表
參數
------------------------------------------
-F fs 將 fs 作為文件列表的分隔符
-f abc 從文件 abc 中讀取 awd 命令。和 sed 的 -f 一樣
-v var=value 將 value 賦給變量 var
gawk 是 UNIX awk 的 GUN 版。為了方便,許多 Linux 系統將 /bin/awk 鏈接到
/bin/gawk
命令
------------------------------------------
模式 {動作}
和 sed 一樣. gawk
也提供一個正則表達式,來選擇需要處理的行。如果不提供表達式,則會處理所有行。表達式后是要處理的動作,如果不提供動作。gawk
會把行內容輸出到標準輸出。
表達式:
------------------------------------------
包括在兩個斜杠中: /表達式/
~ 操作符用于測試某個或者變量是否匹配正則表達式。
!~用于測試不匹配。
數值和字符串的比較還可以用:
=, >
還可以用 ||, && 來比較。
另外還包括兩個 gawk 特殊的命令: BEGIN, END.
gawk 開始處理之前,執行 BEGIN 模式關聯的活動,處理完所有的動作后執行 END 關聯的動作。
逗號(,)是范圍操作符。如果在一個 gawk 程序行上用逗號將兩個模式隔開,gawk 先匹配第 1
個模式,范圍是從第一行,到匹配第 2 個模式的那行。若沒有匹配第 2 個模式的文本行,gawk
將選取直到輸入文件最后的一行。然后再匹配第 2 個模式。完成后,它將再次查找第 1 個模式,如此反復。
動作:
------------------------------------------
匹配到符合條件的行后,gawk
就會對這些行進行相應的動作處理。動作都是包括在大括號{}中的。若沒有添加,會默認給它一個{print}動作,即把所匹配的行打印到標準輸出上。可以將
print 的內容輸出到其它文本中,如:>, >>, |, |&
若是想執行多個動作,可以用分號將多個動作隔開。
gawk 不處理以 # 號開關的程序行。所以,可以在 gawk 命令文件中用 # 添加注釋。
gawk 中我們可以自己聲明變量,數值變量默認值是 0,字符串為空。同時,gawk
還有類似全局變量。我們可以直接訪問:
$0 當前記錄
$1-$n 當前記錄中的字段
FILENAME 當前輸入文件名, 若值為 null 表示是標準輸入
FS 輸入字段分隔符(查看前面的命令參數)
NF 當前記錄的字段數目
NR 當前記錄的記錄編號
OFS 輸出字段分隔符, 默認是空格
ORS 輸出記錄分隔符, 默認是換行符
RS 輸入記錄分隔符, 默認是換行符
函數:
------------------------------------------
對數字和字符串的一些函數:
length(str) 返回 str 中的字符個數;如果沒有傳參數,則返回當前記錄中的字符個數
int(num) 返回 num 的整數部分
index(str1, str2) 返回 str2 在 str1 中的位置。如果 str 不存在, 返回 0
split(str,arr,del) 用 del 作為定界符,切割 str 成數組.返回數組的長度
sprintf(fmt,args) 格式化 args 并返回格式化后的字符串
substr(str,pos,len) 返回 str 中從 pos 開始,長度為 len 的字符串
tolower(str) 將 str 中所有大寫字母變成小寫, 然后返回
toupper(str) 將 str 中所有小寫字母變成大寫, 然后返回
算術操作符
------------------------------------------
*, /, %, +, -, =, ++, --, +=, -=, *=, /=, %=
關聯數組
------------------------------------------
和 PHP 的數組一樣, gawk 的數組可以使用字符串作為索引。使用方式也類似:
array[key]=value;
for(loop in array)...
printf
------------------------------------------
printf 用來代替 print, 格式化 gawk 的輸出。語法如下:
printf "格式", arg1, arg2, ..., argn
"格式" 決定了 printf 如何格式化后面的參數。這些參數可以是變量,也可以是其他表達式。格式中,\n 表示換行;\t
表示 tab 。
一個 arg 就是對應一個格式。格式的語法是:
%[-][x[.y]]conv
叵帶上 - 參數,表示參數左對齊,x 表示最小字段寬度,.y 表示數字中小數點右邊的位數。conv
表示數值轉換的類型,類型有:
d 十進制的數字
e 指數表示
f 浮點數
g 使用 f 或 e 中較短的那個
o 無符號八進制
s 字符串
x 無符號 16 進制
結構控制
------------------------------------------
if..else
如:
if($5 <= 5000){
print $0
}
while
如:
while(n <= 5){
print n
n++
}
for
for(i=1;i<=5;i++){
print i
}
for(loop in array){
print loop
}
break: 退出 for 或 while
continue: 跳出本次循環,進入下一個循環
測試
===================================================
建立測試文件: cars.txt
內容是:
[root@localhost wwwlogs]# cat cars.txt
plym fury 1970 73 2500
chevy malibu 1999 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
bmw 3251 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
chevy impata 1985 85 1550
ford explor 2003 25 9500
簡單命令--不寫模式
----------------------------------------
[root@localhost wwwlogs]# gawk '{print}'
cars.txt
plym fury 1970 73 2500
chevy malibu 1999 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
bmw 3251 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
chevy impata 1985 85 1550
ford explor 2003 25 9500
簡單動作--不寫動作
----------------------------------------
[root@localhost wwwlogs]# gawk '/chevy/'
cars.txt
chevy malibu 1999 60 3000
chevy malibu 2000 50 3500
chevy impata 1985 85 1550
不寫動作時, gawk 會默認添加一個 print 動作.
注意: gawk 中可以不用單引號將命令包起來.但包起來要好一些.萬一命令里有特殊字符呢.
字段
----------------------------------------
前面介紹過,在 gawk 中,用 $0-$n 表示第 n 個字段.
[root@localhost wwwlogs]# gawk '{print $3, $1}'
cars.txt
1970 plym
1999 chevy
1965 ford
1998 volvo
2003 ford
2000 chevy
1985 bmw
2001 honda
2004 ford
2002 toyota
1985 chevy
2003 ford
上面的命令處理所有的行, 且打印第 3 個字段, 以及第 1 個字段. 且中間加一個空格.
注: 多個字段之間用逗號分隔
延伸一下:
[root@localhost wwwlogs]# gawk '/chevy/ {print $3, $1}'
cars.txt
1999 chevy
2000 chevy
1985 chevy
[root@localhost wwwlogs]# gawk '/h/'
cars.txt
chevy malibu 1999 60 3000
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
honda accord 2001 30 6000
chevy impata 1985 85 1550
~ 是匹配操作符.
----------------------------------------
用來指定要匹配的模式在哪個字段中:
[root@localhost wwwlogs]# gawk '$1 ~ /h/'
cars.txt
chevy malibu 1999 60 3000
chevy malibu 2000 50 3500
honda accord 2001 30 6000
chevy impata 1985 85 1550
上面是在第一個字段中查找有 h 的行.
在模式中加上復制點的正則:
^ 它指定必須在行首進行匹配:
----------------------------------------
[root@localhost wwwlogs]# gawk '$1 ~ /^h/'
cars.txt
honda accord 2001 30 6000
中括號指定在括號中的內容中選擇
----------------------------------------
[root@localhost wwwlogs]# gawk '$2 ~ /^[tm]/ {print $3, $2,
"$"$5}' cars.txt
1999 malibu $3000
1965 mustang $10000
2003 thundbd $10500
2000 malibu $3500
2004 taurus $17000
注意: $
符號在模式中,若后面緊跟一個數字,表示第幾個字段。但它在正則中還表示行尾:
----------------------------------------
[root@localhost wwwlogs]# gawk '$3 ~ /5$/ {print $3, $1,
"$"$5}' cars.txt
1965 ford $10000
1985 bmw $450
1985 chevy $1550
上面命令找出了第三列以 5 為結尾的行
模式中還可以加入其它操作符.來進行邏輯比較:
----------------------------------------
[root@localhost wwwlogs]# gawk '$3 == 1985 {print $3, $1,
"$"$5}' cars.txt
1985 bmw $450
1985 chevy $1550
[root@localhost wwwlogs]# gawk '$5 <= 3000 {print $3, $1,
"$"$5}' cars.txt
1970 plym $2500
1999 chevy $3000
1985 bmw $450
2002 toyota $750
1985 chevy $1550
另外,數值的比較和字符串的比較不一樣.字符串是按 ascii 來比較的
看下例:
[root@localhost wwwlogs]# gawk '"2000" <= $5 && $5
< "9000" {print $3, $1, "$"$5}' cars.txt
1970 plym $2500
1999 chevy $3000
2000 chevy $3500
1985 bmw $450
2001 honda $6000
2002 toyota $750
[root@localhost wwwlogs]# gawk '2000 <= $5 && $5
< 9000 {print $3, $1, "$"$5}' cars.txt
1970 plym $2500
1999 chevy $3000
2000 chevy $3500
2001 honda $6000
范圍操作符: ,
----------------------------------------
[root@localhost wwwlogs]# gawk '/volvo/ , /bmw/'
cars.txt
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
bmw 3251 1985 115 450
范圍操作符前面已經介紹過.
在本例中詳細進行解讀:
上面示例選中從包含 volvo 的行開始,到包含 bmw 的行結束之間的所有文本行。
再看一例:
[root@localhost wwwlogs]# gawk '/chevy/ , /ford/'
cars.txt
chevy malibu 1999 60 3000
ford mustang 1965 45 10000
chevy malibu 2000 50 3500
bmw 3251 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
chevy impata 1985 85 1550
ford explor 2003 25 9500
注意,原始文件如下:
plym fury 1970 73 2500
chevy malibu 1999 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
bmw 3251 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
chevy impata 1985 85 1550
ford explor 2003 25 9500
查找過程是:
1.先找 chevy 的行, 找出了第 2 行, 再找 ford, 找出了第 3 行.這樣就選擇了第 2, 3
行
2.再找 chevy 的行, 找出了第 6 行, 再找 ford, 找出了第 9 行.這樣就選擇了 6, 7, 8, 9
行
3.再找 chevy 的行, 找出了第 11 行, 再找 ford, 找出了第 12 行.這樣就選擇了 11, 12
行
4...如此重復上面的查找.
第 5 行被過濾掉了.因為第二次查找是從第 6 行開始的.
============================================================
基本用法結束
============================================================
若 gawk 命令較長.可以將命令放在外部文件中, 在命令中通過 -f filename 來引入.
建立命令文件 pr_header 內容如下:
[root@localhost wwwlogs]# cat
pr_header
BEGIN {print "Make Model Year Miles Price"}
{print}
命令第一行輸出一串字符串.第二行是一個缺少模式的命令.它會輸出所有的行.
執行結果:
[root@localhost wwwlogs]# gawk -f pr_header
cars.txt
Make Model Year Miles Price
plym fury 1970 73 2500
chevy malibu 1999 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
bmw 3251 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
chevy impata 1985 85 1550
ford explor 2003 25 9500
輸出了上面一串表頭, 然后輸出文件中的所有內容
注意: BEGIN{} 中的內容會在 gawk 處理行之前就執行.而 END{} 會在處理完后再執行.
再看另一例:
[root@localhost wwwlogs]# cat
pr_header2
BEGIN {
print "Make Model Year Miles Price"
print "---------------------------------------"
}
{print}
[root@localhost wwwlogs]# gawk -f pr_header2
cars.txt
Make Model Year Miles Price
---------------------------------------
plym fury 1970 73 2500
chevy malibu 1999 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
bmw 3251 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
chevy impata 1985 85 1550
ford explor 2003 25 9500
length 函數
---------------------------------------
[root@localhost wwwlogs]# gawk '{print length, $0}' cars.txt |
sort -n
22 bmw 3251 1985 115 450
23 plym fury 1970 73 2500
24 volvo s80 1998 102 9850
25 ford explor 2003 25 9500
25 toyota rav4 2002 180 750
26 chevy impata 1985 85 1550
26 chevy malibu 1999 60 3000
26 chevy malibu 2000 50 3500
26 ford taurus 2004 10 17000
26 honda accord 2001 30 6000
27 ford mustang 1965 45 10000
27 ford thundbd 2003 15 10500
上例中使用了不傳參數的 length 函數, 它會返回當前行的字符個數,包含字段分隔符.$0 表示當前行.輸出后, gawk
將結果發送到 sort , -n 參數會根據文本行的長度進行排序.
NR
---------------------------------------
[root@localhost wwwlogs]# gawk 'length > 24 {print NR, $3,
$1, "$"$5}' cars.txt
2 1999 chevy $3000
3 1965 ford $10000
5 2003 ford $10500
6 2000 chevy $3500
8 2001 honda $6000
9 2004 ford $17000
10 2002 toyota $750
11 1985 chevy $1550
12 2003 ford $9500
另一例:
[root@localhost wwwlogs]# gawk 'NR == 2, NR == 4'
cars.txt
chevy malibu 1999 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
if
---------------------------------------
[root@localhost wwwlogs]# cat
separ_demo
{
if($1 ~ /ply/) $1 = "Plymouth"
if($1 ~ /chev/) $1 = "Chevrolet"
}
[root@localhost wwwlogs]# gawk -f separ_demo
cars.txt
Plymouth fury 1970 73 2500
Chevrolet malibu 1999 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
Chevrolet malibu 2000 50 3500
bmw 3251 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
Chevrolet impata 1985 85 1550
ford explor 2003 25 9500
它的功能是: 如果第一列中符合模式 ply, 就將第一列改成 Plymouth, 若符合 chev, 就改為:
Chevrolet
獨立腳本
---------------------------------------
每次執行命令時, 我們都要輸入 gawk 然后加參數命令之類的,較麻煩.下面有個簡單辦法:
建立一個命令文件 separ_demo2 內容如下:
[root@localhost wwwlogs]# cat separ_demo2
#!/bin/gawk -f
{
if($1 ~ /ply/) $1 = "Plymouth"
if($1 ~ /chev/) $1 = "Chevrolet"
}
給命令文件加上執行權限:
chmod +x separ_demo2
[root@localhost wwwlogs]# ./separ_demo2
cars.txt
Plymouth fury 1970 73 2500
Chevrolet malibu 1999 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
Chevrolet malibu 2000 50 3500
bmw 3251 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
Chevrolet impata 1985 85 1550
ford explor 2003 25 9500
OFS
---------------------------------------
通過修改 OFS 可以將輸出字段的分隔符用指定字符替換:
printf
---------------------------------------
[root@localhost wwwlogs]# cat
printf_demo
BEGIN{
print " Miles"
print "Make Model Year (000) price"
"----------------------------------------------------------------------------"
}
{
if($1 ~ /ply/) $1 = "Plymouth"
if($1 ~ /chev/) $1 = "Chevrolet"
printf "%-10s %-8s - ] $%-8.2f\n",$1,$2,$3,$4,$5
}
[root@localhost wwwlogs]# gawk -f printf_demo
cars.txt
Miles
Make Model Year (000) price
----------------------------------------------------------------------------
Plymouth ?fury ?1970 ?73
$2500.00
Chevrolet malibu ?1999 ?60
$3000.00
ford ?mustang 1965 ?45 $10000.00
volvo ?s80
1998 ?102
$9850.00
ford ?thundbd 2003 ?15 $10500.00
Chevrolet malibu ?2000 ?50
$3500.00
bmw ?3251 ?1985
115 $450.00
honda ?accord
2001 ?30
$6000.00
ford ?taurus ?2004 ?10
$17000.00
toyota ?rav4
2002 ?180
$750.00
Chevrolet impata ?1985 ?85
$1550.00
ford ?explor ?2003 ?25
$9500.00
重定向輸出
---------------------------------------
下面文件輸出兩個文件.
[root@localhost wwwlogs]# cat
redirect_out
/chevy/ {print > "chevfile"}
/ford/ {print > "fordfile"}
END {print "done."}
[root@localhost wwwlogs]# gawk -f redirect_out
cars.txt
done.
[root@localhost wwwlogs]# cat chevfile
chevy malibu 1999 60 3000
chevy malibu 2000 50 3500
chevy impata 1985 85 1550
總結
以上是生活随笔為你收集整理的linux中gawk用法,Linux - gawk 命令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [力扣刷题总结](双指针篇)
- 下一篇: unix/Linux系统下的nobody