SHELL腳本學習(十四)gawk進階

一、使用變量

gawk支持兩種變量

  • 內建變量
  • 自定義變量
1.1 內建變量
1.1.1 字段和記錄分隔符變量

數據字段變量允許使用美元符號 $ 和 位置來引用對應的字段。 $1 對應第一個數據字段,$2對應第二個數據字段,以此類推。

數據字段用字段分隔符劃定。默認情況下,字段分隔符是一個空白字符(空格或制表符)。可以通過 -F選項修改字段分隔符。也可以使用特殊的內建變量FS修改字段分隔符。

有一組內建變量可以控制輸入和輸出數據中字段和記錄的處理方式:

gawk數據字段和記錄變量

變 量描 述
FIELDWIDTHS由空格分隔的一串數字,定義了每個數據字段的確切寬度
FS輸入字段分隔符
RS輸入記錄分隔符
OFS輸出字段分隔符
ORS輸出記錄分隔符
$ cat < data1
header line
data line 1
End of data line#默認情況
$ gawk '{print $1,$2}' data1
header line
data line
End of#1、OFS測試$ gawk 'BEGIN{OFS="|-|"}
{print $1,$2}' data1
header|-|line
data|-|line
End|-|of#2、ORS測試$ gawk 'BEGIN{ORS="|-|"}
{print $1,$2}
END{print "\n"}' data1 
header line|-|data line|-|End of|-|

默認輸出字段分隔符是空格,第1個例子將輸出字段分隔符換成了"|-|“。
默認輸出記錄分隔符是換行,第2個例子將輸出記錄分隔符換成了”|-|"。

FIELDWIDTHS會根據提前設置好的字段寬度來劃分字段。

下面這個例子將固定格式的時間劃分成 年、月、日、時、分

$ cat <data2
202401011015
202402020900
202403030130$ gawk 'BEGIN{
FIELDWIDTHS="4 2 2 2 2 2"}
{print $1,$2,$3,$4,$5}' data2
2024 01 01 10 15 
2024 02 02 09 00 
2024 03 03 01 30 

FS默認為空白符,RS默認為換行符。也就是說gawk默認一行為一條記錄。但有時一行數據是一個字段,多行數據組成一條記錄。這時可以將FS設置成\n,將RS設置成空字符串。

$ cat <data3
zhangsan
17
haerbinlisi
20
beijing$ gawk 'BEGIN{FS="\n";RS=""}
{print"name:"$1,"age:"$2,"city:"$3}' data3
name:zhangsan age:17 city:haerbin
name:lisi age:20 city:beijing
1.1.2 數據變量

除了字段和記錄分隔符變量外,gawk還提供了其他一些變量幫助了解數據的變化。

更多的gawk內建變量

變量描述
ARGC命令行參數的數量
ARGIND當前處理的文件在ARGV中的索引
ARGV包含命令行參數的數組
CONVFMT數字的轉換格式(參見printf語句),默認為%.6g
ENVIRON當前環境變量及其值組成的關聯數組
ERRNO當讀取或關閉輸入文件發生錯誤時的系統錯誤號
FILENAME用作gawk輸入的數據文件的名稱
FNR當前數據文件中已處理的記錄數
IGNORECASE非0表示忽略大小寫
NF數據文件中的字段總數
NR已處理的輸入記錄數
OFMT數字的輸出格式。默認值為%.6g。以浮點數或科學計數法表示,以較短者為準,最多是使用6位小數
RLENGTH由match函數所匹配的子串長度
RSTART由match函數所匹配的子串的起始位置

下面測試幾個常用的變量

#ARGC:命令行參數的數量
#ARGV:當前處理的文件在ARGV中的索引
$ gawk 'BEGIN{print ARGC,ARGV[0],ARGV[1],ARGV[2]}' data1 data2
3 gawk data1 data2#ENVIRON:當前環境變量及其值組成的關聯數組
$ gawk 'BEGIN{print ENVIRON["HOME"]}' 
/home/ubuntu#FILENAME :用作gawk輸入的數據文件的名稱
$ gawk 'END{print FILENAME}' data1
data1
$ cat < data1
header line
data line 1
End of data line$ cat <data2
202401011015
202402020900
202403030130#NR:已處理的輸入記錄數
#FNR:當前數據文件中已處理的記錄數
#NF:數據文件中的字段總數
#$NF:最后一個字段的值
$ gawk '{print "NR="NR,"FNR="FNR,"NF="NF,"$NF="$NF}' data1 data2
NR=1 FNR=1 NF=2 $NF=line
NR=2 FNR=2 NF=3 $NF=1
NR=3 FNR=3 NF=4 $NF=line
NR=4 FNR=1 NF=1 $NF=202401011015
NR=5 FNR=2 NF=1 $NF=202402020900
NR=6 FNR=3 NF=1 $NF=202403030130
NR=7 FNR=4 NF=0 $NF=
1.2 自定義變量

gawk的自定義變量由任意個字母、數字和下劃線組成,但不能以數字開頭。
gawk自定義變量區分大小寫。

1.2.1 在腳本中為變量賦值
$ gawk 'BEGIN{test="this is a test.";print test}'
this is a test.$ gawk 'BEGIN{test=100;print test*(test-1)}'
9900$ gawk 'BEGIN{test=100;print test^2}'
10000
1.2.2 在命令行中給變量賦值
$ cat <data1
header line
data line 1
End of data line$ gawk '{print $field}'  field=1 data1
header
data
End$ gawk '{print $field}'  field=2 data1
line
line
of

這個例子通過在命令行中給變量賦值,可以顯示不同的字段。
這個特性可以在不改變腳本代碼的情況下改變腳本的行為。

使用命令行參數定義變量有一個問題:設置變量后,這個變量在BEGIN模塊不可用
如下:

$ gawk 'BEGIN {print "field="field}' field=3 data1
field=

可以用 -v選項解決這個問題。-v選項允許在BEGIN之前定義變量。

$ gawk -v field=3 'BEGIN {print "field="field}' field=3 data1
field=3
二、處理數組

數組用于單個變量存儲多個值,gawk語言使用關聯數組提供數組功能。類似c++中的unorder_map。

2.1 定義數組變量

可以用賦值語句定義數組變量。格式如下;

var[index]=element
var:數組變量名
index:索引
element:索引對應的值

$ gawk 'BEGIN{arr["name"]="lilei";arr["age"]=20;
print arr["name"],arr["age"]}'
lilei 20
2.2 遍歷數組變量

格式:

for index in array
{
?statement
}

for語句每次循環時會把下一個數組元素的索引賦值給index。

$ gawk 'BEGIN{arr["name"]="lilei";arr["age"]=20;
for (ind in arr)
{
print "arr["ind"]="arr[ind]
}}'
arr[age]=20
arr[name]=lilei

索引沒有固定的返回順序。

2.3 刪除數組變量

從關聯數組中刪除數據需要使用 delete 命令;

delete array[index]

下面使用delete命令的例子

$ cat < gawk_cmd
BEGIN {arr["name"]="lilei";arr["age"]=20;arr["city"]="haerbin";for (ind in arr){print "arr["ind"] :" arr[ind];}delete arr["age"];print "---------"for (ind in arr){print "arr["ind"] :" arr[ind];}
}$ gawk -f gawk_cmd
arr[age] :20
arr[city] :haerbin
arr[name] :lilei
---------
arr[city] :haerbin
arr[name] :lilei

每行代碼后面的分號 ( ; ) 寫不寫都行。

三、 使用模式
3.1 正則表達式

sed 只支持基礎正則表達式(BRE),gawk支持基礎正則表達式(BRE) 和擴展正則表達式(ERE)。

下面的第1個例子輸出張三的年齡,第2個例子輸出年齡在20~30之間的人的名字。

$ cat <data3
zhangsan
17
haerbinlisi
20
beijing$ gawk 'BEGIN{FS="\n";RS=""}
/zhangsan/{print $2}' data3
17$ gawk 'BEGIN{FS="\n";RS=""}
/2./{print $1}' data3
lisi
3.2 匹配操作符

匹配操作符 (~) 使用格式:

數據字段 ~ /正則表達式/

和上面的例子相同,下面第1個例子輸出zhangsan的年齡,第2個例子輸出年齡在20~30之間的人的名字。


$ gawk 'BEGIN{FS="\n";RS=""}
$1 ~ /zhangsan/{print $1,$2,$3}' data3
zhangsan 17 haerbin$ gawk 'BEGIN{FS="\n";RS=""}
$2 ~ /^2.$/{print $1,$2,$3}' data3
lisi 20 beijing
3.3 數學表達式

處理正則表達式,gawk還可以在匹配模式中使用數學表達式。
可以使用任何常見的數學表達式:

操作符描述
==等于
<=小于等于
<小于
>大于
>=大于等于

還是相同的例子,輸出張三的年齡

$ cat <data3
zhangsan
17
haerbinlisi
20
beijing$ gawk 'BEGIN{FS="\n";RS=""}
$1=="zhangsan"{print "age="$2}' data3
age=17
四、結構化命令

gawk 中的結構化命令和 c語言 中的分支和循環結構基本一致。

4.1 if語句

輸出年齡是否大于18歲

$ cat <data3
zhangsan
17
haerbinlisi
20
beijing$ cat < gawk_cmd
BEGIN {FS="\n"RS=""print "Begin"
}{cmp=""age=18if ($2 <= age){cmp=" less than "}else{cmp=" greater than "}print $1 cmp,age
}END{print "End of file"
}$ gawk -f gawk_cmd data3
Begin
zhangsan less than  18
lisi greater than  18
End of file
4.2 while 語句

格式:

while (condition)
{
?statements
}

下面例子輸出某次跳遠比賽各個選手的平均成績。

$ cat < data1
5.5 6.5 7.5
6.6 6.5 6.5
6.6 7.5 5.9$ cat < gawk_cmd
BEGIN {print "Begin"
}{i=1sum=0.0while (i <= NF){sum+=$ii++}print sum/NF
}END{print "End of file"
}$ gawk -f gawk_cmd data1
Begin
6.5
6.53333
6.66667
End of file
4.3 do-while語句

格式:

do
{
?statements
}
while (condition)

do-whilewhile 唯一區別是 do-while保證statements會在條件被求值之前至少執行一次。

4.4 for語句

格式:

for (變量賦值; condition; 迭代處理)
{
?statements
}

下面使用for語句計算跳遠比賽的平均成績。

$ cat < gawk_cmd
BEGIN {print "Begin"
}{sum=0.0for(i=1;i<=NF;i++){sum+=$i}print sum/NF
}END{print "End of file"
}$ gawk -f gawk_cmd data1
Begin
6.5
6.53333
6.66667
End of file
五、格式化打印
5.1 printf 命令

gawk中的printf命令和 C語言 中的printf函數一樣。
格式:

printf “format string”,var1,var2…

格式說明符的控制字母

控制字母描述
c數字作為ASCII字符顯示
d和i顯示整數值
e用科學計數法顯示數字
f顯示浮點數
g用科學計數法或浮點數顯示(較短的格式有限)
o顯示八進制
s顯示字符串
x顯示十六進制
X顯示十六進制,但用大寫字母A-F
#將輸入數據當做字符串
$ echo "200.33333"| gawk '{printf "%s\n",$1}'
200.33333#將輸入數據當作小數并保留兩位小數
$ echo "200.33333"| gawk '{printf "%2.2f\n",$1}'
200.33#將輸入數據當作整數,并且至少輸出5位,不足5位向前補0
$ echo "200.33333"| gawk '{printf "%05d\n",$1}'
00200
六、自定義函數
6.1 定義函數

格式:

function name ([variables])
{
? statements
}

6.2 使用函數

使用自定義函數計算平均成績

$ cat < gawk_cmd
function average(s1,s2,s3)
{return (s1 + s2 + s3)/3
}BEGIN {print "Begin"}{printf "average scores:%.2f\n",average($1,$2,$3)
}END{print "End of file"
}$ gawk -f gawk_cmd data1
Begin
average scores:6.50
average scores:6.53
average scores:6.67
End of file
6.3 函數庫

也可以把常用的函數放到一個文件中,封裝成函數庫。

$ cat < lib_func
function average(s1,s2,s3)
{return (s1 + s2 + s3)/3
}$ cat < lib_func
function average(s1,s2,s3)
{return (s1 + s2 + s3)/3
}
ubuntu@VM-8-14-ubuntu:~$ cat < gawk_cmdBEGIN {print "Begin"
}{printf "average scores:%.2f\n",average($1,$2,$3)
}END{print "End of file"
}$ gawk -f lib_func -f gawk_cmd  data1
Begin
average scores:6.50
average scores:6.53
average scores:6.67
End of file

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/37736.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/37736.shtml
英文地址,請注明出處:http://en.pswp.cn/web/37736.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【基于R語言群體遺傳學】-1-哈代溫伯格基因型比例

前言 群體遺傳學是研究生物群體中基因的分布、基因頻率和基因型頻率的維持和變化的學科。它不僅探討遺傳病的發病頻率和遺傳方式&#xff0c;還研究基因頻率和變化的規律&#xff0c;為預防、監測和治療遺傳病提供重要信息。R語言作為一種強大的統計分析工具&#xff0c;在群體…

mybatis實現多表查詢

mybatis高級查詢【掌握】 1、準備工作 【1】包結構 創建java項目&#xff0c;導入jar包和log4j日志配置文件以及連接數據庫的配置文件&#xff1b; 【2】導入SQL腳本 運行資料中的sql腳本&#xff1a;mybatis.sql 【3】創建實體來包&#xff0c;導入資料中的pojo 【4】User…

TypeScript Project References npm 包構建小實踐

npm 包輸出 es/cjs 產物 在開發一個 npm 包時&#xff0c;通常需要同時輸出 ES 模塊和 CommonJS 模塊的產物供不同的構建進行使用。在只使用tsc進行產物編譯的情況下&#xff0c;我們通常可以通過配置兩個獨立的 tsconfig.json 配置文件&#xff0c;并在一個 npm script 中 執…

kubesphere自定義流水線基礎鏡像

背景 需求&#xff1a;在流水線基礎pod中使用python和jinja2模塊來動態渲染部署文件 由于ks提供的基礎鏡像無法滿足以上需求&#xff0c;在ks提供的maven鏡像的基礎上實現 實施 制作鏡像&并推送到private image repo FROM kubesphere/builder-maven:v3.2.0 RUN sed -i…

7.1作業

1.思維導圖 2.在堆區申請兩個長度為32的空間&#xff0c;實現兩個字符串的比較【非庫函數實現】 (1)定義函數&#xff0c;在對區申請空間 兩個申請&#xff0c;主函數需要調用2次 (2)定義函數&#xff0c;實現字符串的輸入 void input(char *p) (3)調用函數實現字符串比較…

BUT000增強字段BAPI結構激活出錯(BUPA_CENTRAL_CI_CHANGE)

導語&#xff1a;BP主數據增強字段&#xff0c;需要使用BAPI&#xff1a;BUPA_CENTRAL_CI_CHANGE進行值寫入&#xff0c;但是在SAP 2023以后的版本&#xff0c;激活會出錯&#xff0c;原因是因為SAP的一個結構同時包含了BUS00_EEW以及BUS00_EEWX兩個結構&#xff0c;導致結構字…

Spring Security 認證流程

Spring Scurity是spring生態下用于認證和授權的框架&#xff0c;具有高度的靈活性和可擴展行&#xff0c;本節主要對Spring Security的認證過程中進行概括性的介紹&#xff0c;主要介紹在該過程中&#xff0c;會涉及到哪些組件以及每個組件所承擔的職責&#xff0c;希望大家可以…

Elasticsearch 配置說明

# ---------------------------------- Cluster ----------------------------------- cluster.name: yh-es # es名稱 # ------------------------------------ Node ------------------------------------ node.name: xibo-es node.master: true node.da…

電腦錄音軟件哪個好?7款錄制音頻工具大盤點,趕快學起來!(2024)

也許你渴望提取你最喜歡的節目的背景音樂&#xff0c;或者你希望錄制自己的聲音制作教程。如果是這樣&#xff0c;你就需要一款優秀的電腦錄音軟件&#xff0c;來幫助你捕捉任何你想要的聲音&#xff0c;而且不會損失音質。目前市場上存在著大量的錄制音頻工具&#xff0c;面對…

鎖相環相位噪聲仿真代碼-匯總

24小時自動發貨 所設計的壓控振蕩器輸入電壓為0.625V時&#xff0c;輸出大致為500Mhz&#xff1b;輸入電壓為1.559時&#xff0c;輸出電壓大致為1Ghz 1.文件夾里面各個文件作用&#xff08;包括參考書PLL PHASE NOISE ANALYSIS、lee的射頻微電子、以及前人留下的matlab文件還有…

ModStart:開源免費的PHP企業網站開發建設管理系統

大家好&#xff01;今天我要給大家介紹一款超級強大的開源工具——ModStart&#xff0c;它基于Laravel框架&#xff0c;是PHP企業網站開發建設的絕佳選擇&#xff01; 為什么選擇ModStart&#xff1f; 模塊化設計&#xff1a;ModStart采用模塊化設計&#xff0c;內置了眾多基…

Ubuntu(通用)—網絡加固—防DNS污染和ARP欺騙

1. 防DNS污染 DNS協議&#xff0c;把域名解析成ip地址&#xff0c;udp&#xff0c;這個過程會暴露訪問的域名&#xff0c; 對這一傳輸過程加密&#xff08;傳輸層用tcp&#xff09;即為DoH(DNS over HTTPS)。 Browser(firefox)加固 由于Cloudflare、Quad8的DoH服務器不能用&…

三維重建基礎【知識點總結】

三維重建基礎【知識點總結】 rasterizationvolumetric ray-marchingSfM&#xff08;Structure from Motion&#xff09;Spherical Harmonics多視圖立體&#xff08;Multiple View Stereo, MVS&#xff09;動畫制作專業術語 rasterization Rasterization&#xff0c;中文通常譯…

雅思詞匯及發音積累 2024.7.1

旅游場景 1.credit card 信用卡 2.driving license/licence 駕照 3.expire /?k?spa??(r)/ 駕照/護照等過期 4.platform 站臺 5.Currency 貨幣 6.Pound 英鎊 7.Deserts /d??z??ts/ 沙漠 8. hilly areas 丘陵地帶 9.wetlands 沼澤地 10.bushlands 灌木叢 11.tropi…

Dns被莫名篡改的問題定位(筆記)

引言&#xff1a;最近發現用戶的多臺機器上出現了Dns被莫名修改的問題&#xff0c;從系統事件上看并未能正常確定到是那個具體軟件所為&#xff0c;現在的需求就是確定和定位哪個軟件具體所為。 解決思路&#xff1a; 首先到IPv4設置頁面對Dns進行設置&#xff1a;通過ProcExp…

缺失d3dx9_43.dll是怎么回事?教你幾種靠譜的解決方法

在日常生活和工作中&#xff0c;電腦已經成為我們不可或缺的工具。然而&#xff0c;在使用電腦的過程中&#xff0c;我們常常會遇到一些問題&#xff0c;其中之一就是軟件運行時提示d3dx9_43.dll丟失。這個問題會導致軟件游戲無法啟動運行&#xff0c;但只要我們了解其原因和解…

LinkedHashMap、TreeMap

LinkedHashMap&#xff1a; 有序、不重復、無索引&#xff0c;底層是雙鏈表 TreeMap&#xff1a;底層基于紅黑樹&#xff0c;可以對鍵進行排序 默認排序&#xff1a;integer和string都是從小到大排序 例題&#xff1a;

git合并分支的疑問

今天遇到一個奇怪的問題&#xff1a; 1、后端從master拉了三個分支。分別為dev、test、和stage。 2、研發1從dev拉了分支feature1,然后commit、commit、commit……。最后request merge到dev、test和stage。成功了。 3、研發2從dev拉了分支feature2,注意&#xff0c;feature2…

Dataweave2 語法教程

DataWeave 是 MuleSoft 的數據語言&#xff0c;專門用于數據轉換和映射。在 MuleSoft 的 Anypoint Platform 中&#xff0c;它是數據集成的一部分。下面是一個 DataWeave 語法教程&#xff0c;涵蓋基本的語法和用法。 基本語法 DataWeave 腳本分為三個部分&#xff1a;%dw 聲…

SpringBoot整合WebClient進行Http遠程調用

使用WebClient進行Http遠程調用 文章目錄 使用WebClient進行Http遠程調用1.WebClient對象創建2.WebClient對象抽取config配置3.Get請求url參數設置4.獲取ResponseEntity對象5.Post請求測試示例代碼 WebClient 一旦創建&#xff0c;就是不可修改的&#xff0c;如果需要設置默認值…