AWK再次認識--內置的參數,以及編寫腳本

原本這是篇給公司內同事寫的培訓文章,對于初學awk的人還蠻有幫助,貼到這里與大家共享一下。

〇、前言

??? 意見反饋,請mailto:datouwang@gmail.com。

?

一、AWK簡介

???????? AWK名字來源于三位創造者Aho、Weinberger和Kernighan統稱。

???????? AWK擅長處理文本數據。

?

二、AWK的調用方式

???????? awk [-Ffs] [-v var=value] [program | -f progfile ...] [file ...]

?

??? 1、命令行方式

???????? 例如:

????????

awk '{print $1}' file

ps -ef|grep program|awk '{print $2}'

?

?

???????? 2、文件方式

???????? 例如:

awk -f progfile file

?

????????

???????? 3、文件解釋器方式

???????? AWK腳本文件開頭需要注明調用方式,典型寫法為:

???????? #!/bin/awk -f

??? 注意-f后面有空格。

???????? 腳本文件需要有執行權限,如果沒有需要使用chmod +x progfile賦權。

???????? 例如:

progfile file

?

三、AWK參數

???????? -F? 指定域分隔符,例如:-F "|",即以|作為域分隔符,默認分隔符為一個或多個空格或TAB,即"[[:space:]][[:space:]]*"。

???????? -v? 定義變量,從shell給awk傳遞變量,如-vDATE=$DATE,即將shell中$DATE變量值傳遞給awk變量DATE。

???????? -f? 指定腳本文件,例如-f progfile。

?

四、AWK內置變量

???????? FS????? 域分隔符

???????? NF????? 域個數

???????? NR????? 行數

???????? FNR???? 同上

???????? FILENAME??? 處理的文件名,當輸入為管道時,FILENAME為空。

???????? RS????? 行分隔符

???????? OFS???? 輸出域分隔符

???????? ORS???? 輸出行分隔符

???????? OFMT??????? 數字輸出格式

???????? CONVFMT???? 數字內部轉換格式

???????? SUBSEP????? 多維數組索引分隔符

???????? ARGC??????? 輸入參數個數

???????? ARGV??????? 輸入參數數組

???????? ENVIRON???? 環境變量數組

???????? RSTART????? match()函數正則匹配到字符串開始位置

???????? RLENGTH???? match()函數正則匹配到字符串的長度

?

五、AWK內置函數

???????? blength[([s])]????????? 計算字符串長度(byte為單位)

??? length[([s])]?????????? 計算字符串長度(character為單位)

??? rand()????????????? 生成隨機數

???????? srand([expr])?????????? 設置rand() seed

??? int(x)????????????? 字符串轉換為整型

???????? substr(s, m [, n])????? 取子字符串

???????? index(s, t)???????? 在字符串s中定位t字符串首次出現的位置

???????? match(s, ere)?????????? 在字符串s中匹配正則ere,match修改RSTART、RLENGTH變量。

???????? split(s, a[, fs])?????? 將字符串分割到數組中

???????? sub(ere, repl [, in])?? 字符串替換

???????? gsub??????????????? 同上

???????? sprintf(fmt, expr, ...) 拼字符串

???????? system(cmd)???????? 在shell中執行cmd。

???????? toupper(s)????????? 字符串轉換為大寫

???????? tolower(s)????????? 字符串轉換為小寫

?

?

六、AWK流程控制

???????? if(expression) statement [ else statement ]

??? while(expression) statement

??? for(expression;expression;expression) statement

??? for(var in array) statement

??? do statement while(expression)

??? break

??? continue

??? {[statement? ...]}

??? expression????????? # commonly? var = expression

??? print [expression-list] [ > expression]

??? printf format [, expression-list] [ > expression]

??? return [expression]

??? next??????????????? # skip remaining patterns on this input line.

??? delete array [expression]?? # delete an array element.

??? exit [expression]?? # exit immediately; status is expression.

?

七、AWK簡單應用范例

???????? AWK腳本分為三部分BEGIN段,處理段,END段。其中BEGIN段在第一行讀取之前執行,END段在最后一行處理后執行。

?

1、內容過濾,同"grep tag file"。

#前兩個語句為正則匹配

?

awk '/tag/ {print}' file

awk '{if($0 ~/tag/) print}' file

awk '{if(index($0, "tag") > 0) print}' file

?

?

2、取特定列,同"cut –f1 –f3 –f5 file"。

#輸出文件第1、3、5列

?

awk '{print $1, $3, $5}' file

?

????????

3、對文件內容進行剔重,類似"sort -u file",但未排序。

#如果當前行未存在于rec HASH表中,則記錄此行數據,并輸出

?

awk '{if(!($0 in rec)) {rec[$0]=1; print $0;}}' file

?

???????? AWK中數組有兩種用法普通數組和HASH數組,此處為HASH數組。

????????

?

4、僅輸出數據

#輸出100行數據

?

awk ‘BEGIN {for(i = 0; i < 100; i++) printf("this is %d\n", i);}’

?

可見,如果腳本中只有BEGIN段,可以沒有輸入。

?

5、統計數據

#對第一列和第二列數據進行匯總,最終輸出

?

awk ‘{a+=$1; b+=$2}END{printf("a=%d\n,b=%d\n", a, b);}’ file

?

?

?

八、AWK高級應用范例

?

1、 分組功能,類似Group by功能

#使用第一列作為分組列,第二列為聚合列,即select col1, sum(col2) from file group by col1

?

awk ‘{tot[$1] += $2}END{for(i in tot) printf("%s %d\n", i, tot[i]);}’ file

?

#比上個例子增加一個類似having的用法

?

awk ‘{tot[$1] += $2}END{for(i in tot) if(tot[i] > 10) printf("%s %d\n", i, tot[i]);}’ file

?

#使用第一列作為分組列,第二列、第三列為聚合列

?

awk ‘{tot1[$1] += $2; tot2[$1] += $3;}END{for(i in tot1) printf("%s %d %d\n", i, tot1[i], tot2[i]);}’ file

?

#多維數組例子,可將多個字段作為分組列,AWK使用一維數組模擬多維數組,使用\034作為分隔符

?

awk ‘{tot1[$1, $2] += $3; tot2[$1, $2] += $4;}END{for(i in tot1) printf("%s %d %d\n", i, tot1[i], tot2[i]);}’ file?

?

?

?

2、 文件操作

#將兩個文件根據filename1的第一列和filename2的第二列進行關聯

?

BEGIN {

??????? #讀取filename1文件內容

??????? while((getline < "filename1") != NULL)

??????? {

??????????????? rel[$1] = 1;

??????????????? rec1[$1] = $2;

??????? }

?

??????? while((getline < "filename2") != NULL)

??????? {

??????????????? rel[$2] = 1;

??????????????? rec2[$2] = $3;

??????? }

?

??????? for(i in rel)

??????? {

??????????????? printf("%s %s %s\n", i, rec1[i], rec2[i]);

??????? }

}

?

#將文件按照字段進行拆分

?

{

??????? print $0 >> "split/" substr($1,1,7);

}

?

?

3、 從SHELL向AWK傳遞變量

awk? -vAWK_DATE=$DATE 'BEGIN {print AWK_DATE}'

?

?

4、 在AWK內部讀取shell命令輸出

#讀取ls命令輸出,在AWK中打印輸出

?

BEGIN {

??????? while("ls"|getline)

??????? {

??????????????? print $0;

??????? }

}

?

#讀取date輸出

?

BEGIN {

??????? "date" | getline;

?

??????? print $0;

?

??????? "date +%Y" | getline v_year;

?

??????? print v_year;

}

?

?

?

5、 將AWK輸出通過管道傳遞給SHELL命令

#將打印信息輸出給sort進行排序

?

BEGIN {

??????? for(i = 0; i < 100; i++)

??????? {

??????????????? printf("%03d\n", 100 - i) | "sort";

??????? }

}

?

?

6、 正則表達式簡單例子

#演示正則表達式的使用方法

?

BEGIN {

??????? str1 = "abc.123@gmail.com";

??????? str2 = "123123abcd@gmail.com";

??????? str3 = "&^%76123@gmail.com";

??????? str4 = "zxcvb@sohu.com.cn.1231231";

?

??????? match(str1, "[a-zA-Z][a-zA-Z0-9.]*@[a-zA-Z0-9][a-zA-Z0-9.]*.[a-zA-Z]*[a-zA-Z]");

?

??????? if(RSTART > 0)

??????????????? printf("%s\n", substr(str1, RSTART, RLENGTH));

??????? else

??????????????? printf("[%s] not match\n", str1);

?

??????? match(str2, "[a-zA-Z][a-zA-Z0-9.]*@[a-zA-Z0-9][a-zA-Z0-9.]*.[a-zA-Z]*[a-zA-Z]");

?

??????? if(RSTART > 0)

??????????????? printf("%s\n", substr(str2, RSTART, RLENGTH));

??????? else

??????????????? printf("[%s] not match\n", str2);

?

??????? match(str3, "[a-zA-Z][a-zA-Z0-9.]*@[a-zA-Z0-9][a-zA-Z0-9.]*.[a-zA-Z]*[a-zA-Z]");

?

??????? if(RSTART > 0)

??????????????? printf("%s\n", substr(str3, RSTART, RLENGTH));

??????? else

??????????????? printf("[%s] not match\n", str3);

?

??????? match(str4, "[a-zA-Z][a-zA-Z0-9.]*@[a-zA-Z0-9][a-zA-Z0-9.]*.[a-zA-Z]*[a-zA-Z]");

?

??????? if(RSTART > 0)

??????????????? printf("%s\n", substr(str4, RSTART, RLENGTH));

??????? else

??????????????? printf("[%s] not match\n", str4);

?

?

}

?

?

7、自定義函數

function my_plus(a, b)

{

??????? return a + b;

}

BEGIN {

??????? printf("%d\n", my_plus(123, 321));

}

?

?

九、一些應用范例

???????? 1、驗證話單正確性的一個腳本

/^vc/ {

??????? #取話單中各個變量

??????? call_type = substr($0,3,2);

??????? call_duration = int(substr($0,95,6));

??????? roam_type = substr($0,210,1);

??????? fee_type = substr($0,211,1);

??????? dial_type = substr($0,212,3);

??????? chat_type = substr($0,215,3);

?

??????? cfee = int(substr($0,218,9));

??????? lfee = int(substr($0,236,9));

?

??????? #如果為國際漫游,不分析,跳過

??????? if(roam_type > 4)

??????? {

??????????????? next;

??????? }

?

??????? if(call_type == "01")

??????? {

??????????????? if(substr(dial_type,1,1) != "0")

??????????????? {

???????????????? ???????if(lfee > 0)

??????????????????????? {

??????????????????????????????? printf("%s:LFEE_01\n", $0);

??????????????????????? }

?

??????????????????????? next;

??????????????? }

?

??????????????? if(roam_type != "0")

??????????????? {

?????????????????? ?????if(fee_type == "0" || fee_type == "2" || fee_type == "3")

??????????????????????? {

??????????????????????????????? if(lfee > 0)

??????????????????????????????? {

??????????????????????????????????????? printf("%s:LFEE_ERR02\n", $0)

??????????????????????????????? }

??????????????????????? }

??????????????????????? else

??????????????????????? {

??????????????????????????????? if(cfee > 0)

??????????????????????????????? {

??????????????????????????????????????? printf("%s:CFEE_ERR01\n", $0);

??????????????????????????????? }

??????????????????????? }

??????????????? }

??????????????? else

??????????????? {

??????????????????????? if(fee_type != "0")

??????????????????????? {

??????????????????????????????? if(cfee > 0)

?????????????? ?????????????????{

??????????????????????????????????????? printf("%s:CFEE_ERR02\n", $0);

??????????????????????????????? }

??????????????????????? }

??????????????? }

??????? }

?

??????? if(call_type == "02")

??????? {

??????????????? if(lfee > 0)

??????? ????????{

??????????????????????? printf("%s:LFEE_ERR03\n", $0);

??????????????? }

??????? }

}

?

???????? 2、一個模擬求取批價標批費率計劃的例子

function my_match(str, pat)

{

#for debug

#printf("str==>|%s|,pat==>|%s|\n", str, pat);

?

??????? if(pat == "*")

??????????????? return 1;

?

??????? n = split(pat, arr, ",");

?

??????? for(z = 1; z <= n; z++)

??????? {

??????????????? gsub("\?", "[a-zA-Z0-9]", arr[z]);

?

#for debug

#printf("str==|%s|,arr==>|%s|\n", str, arr[z]);

???????????????

??????????????? match(str, arr[z]);

??????????????? if(RSTART > 0)

??????????????? {

??????????????????????? return 1;

??????????????? }

??????? }

?

??????? return 0;

???????

}

?

BEGIN {

?

??????? dial_cnt = 0;

??????? while((getline < "dial.lst") != NULL)

??????? {

??????????????? dial[dial_cnt] = $1;

?

??????????????? dial_cnt++;

??????? }

?

??????? chat_cnt = 0;

??????? while((getline < "chat.lst") != NULL)

??????? {

??????????????? chat[chat_cnt] = $1;

?

??????????????? chat_cnt++;

??????? }

?

??????? cfg_cnt = 0;

?

??????? while((getline < "plan.lst") != NULL)

??????? {

??????????????? cfg_dial[cfg_cnt] = $1;

??????????????? cfg_chat[cfg_cnt] = $2;

??????????????? cfg_item[cfg_cnt] = $3;

??????????????? cfg_plan[cfg_cnt] = $4;

?

??????????????? cfg_cnt++;

??????? }

?

??????? for(d = 0; d < dial_cnt; d++)

??????? {

??????????????? for(c = 0; c < chat_cnt; c++)

??????????????? {

??????????????????????? printf("%s %s|", dial[d], chat[c]);

???????????????????????

??????????????????????? out_cnt = 0;

?????????????????????? ?

??????????????????????? for(i = 0; i < cfg_cnt; i++)

??????????????????????? {

#for debug

#printf("\n<%d,%d,%d>test match==>|<%s, %s>; <%s, %s>|\n", d, c, i, dial[d], cfg_dial[i], chat[c], cfg_chat[i]);

?

??????????????????????????????? if(my_match(dial[d], cfg_dial[i]) == 1 && my_match(chat[c], cfg_chat[i]) == 1)

??????????????????????????????? {

??????????????????????????????????????? if(out_cnt == 0)

??????????????????????????????????????? {

??????????? ????????????????????????????????????printf("%s %s %s %s\n", cfg_item[i], cfg_plan[i], cfg_dial[i], cfg_chat[i]);

??????????????????????????????????????? }

??????????????????????????????????????? else

??????????????????????????????????????? {

????????????? ??????????????????????????????????printf("%s %s|%s %s %s %s\n", dial[d], chat[c], cfg_item[i], cfg_plan[i], cfg_dial[i], cfg_chat[i]);

??????????????????????????????????????? }

???????????????????????????????????????????????

????????????????????????????? ??????????out_cnt++;

??????????????????????????????? }

??????????????????????? }

???????????????????????

??????????????????????? if(out_cnt == 0)

??????????????????????? {

??????????????????????????????? printf("NULL\n");

??????????????????????? }

?????? ?????????}

??????? }

}

?

?

?

?

?

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

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

相關文章

AWk高級編程

首先再說一說awk的工作流程還是有必要的 : 執行awk時, 它會反復進行下列四步驟. 1. 自動從指定的數據文件中讀取一個數據行. 2. 自動更新(Update)相關的內建變量之值. 如 : NF, NR, $0... 3. 依次執行程序中所有 的 Pattern { Actions } 指令. 4. 當執行完程序中所有 Pattern {…

leetcode19. 刪除鏈表的倒數第N個節點

給定一個鏈表&#xff0c;刪除鏈表的倒數第 n 個節點&#xff0c;并且返回鏈表的頭結點。 示例&#xff1a; 給定一個鏈表: 1->2->3->4->5, 和 n 2. 當刪除了倒數第二個節點后&#xff0c;鏈表變為 1->2->3->5. 說明&#xff1a; 給定的 n 保證是有效…

python模塊(5)-Matplotlib 簡易使用教程

Matplotlib簡易使用教程0.matplotlib的安裝1.導入相關庫2.畫布初始化2.1 隱式創建2.2 顯示創建2.3 設置畫布大小2.4 plt.figure()常用參數3.plt. 能夠繪制圖像類型3.1等高線3.2 箭頭arrow4.簡單繪制小demodemo1.曲線圖demo2-柱狀、餅狀、曲線子圖5.plt.plot()--設置曲線顏色,粗…

random_shuffle 和transform算法

1)STL中的函數random_shuffle()用來對一個元素序列進行重新排序(隨機的),函數原型如下: std::random_shuffle

C語言字符輸出格式化

符號屬性 長度屬性 基本型 所占 位數 取值范圍 輸入符舉例 輸出符舉例 -- -- char 8 -2^7 ~ 2^7-1 %c %c、%d、%u signed -- char 8 -2^7 ~ 2^7-1 %c %c、%d、%u unsigned -- char 8 0 ~ 2^8-1 %c %c、%d、%u [signed] short [int] 16 -2^15 ~ 2^15-1 %hd %hd unsigned short […

leetcode20 有效的括號

給定一個只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串&#xff0c;判斷字符串是否有效。 有效字符串需滿足&#xff1a; 左括號必須用相同類型的右括號閉合。 左括號必須以正確的順序閉合。 注意空字符串可被認為是有效字符串。 示…

python模塊(6)-Pandas 簡易使用教程

Pandas 簡易教程1.Pandas簡介2.創建2.1創建dataFrame2.2創建Series3.dataframe數據訪問3.1 獲取一列--列標簽3.2 獲取多列--列標簽列表3.3 獲取一行--行標簽.loc()3.4 獲取多行--行切片操作.loc()3.5 index 獲取行列信息--df.iloc()3.6 獲取一個元素3.7 布爾值選擇數據4.datafr…

windows 如何查看端口占用情況?

開始--運行--cmd 進入命令提示符 輸入netstat -ano 即可看到所有連接的PID 之后在任務管理器中找到這個PID所對應的程序如果任務管理器中沒有PID這一項,可以在任務管理器中選"查看"-"選擇列" 經常,我們在啟動應用的時候發現系統需要的端口被別的…

泛型lua的for循環以及lua的特殊的dowhile循環

范型for循環&#xff1a; -- print all values of array a a{1,2,3,4,5,6,7}; for i,v in ipairs(a) do print(v) end 范型for遍歷迭代子函數返回的每一個值。 再看一個遍歷表key的例子&#xff1a; -- print all keys of table t map {["gaoke"]1,["gaoxin&…

leetcode1 兩數之和

給定一個整數數組 nums 和一個目標值 target&#xff0c;請你在該數組中找出和為目標值的那 兩個 整數&#xff0c;并返回他們的數組下標。 你可以假設每種輸入只會對應一個答案。但是&#xff0c;你不能重復利用這個數組中同樣的元素。 示例: 給定 nums [2, 7, 11, 15], t…

Linux(5)-用戶/權限-adduser,su,chmod

用戶、權限管理1. adduserstep1: 添加新用戶step2: 賦予sudo權限。step3: 刪除用戶2. useradd &#xff08;建議不要使用&#xff09;3. 切換用戶su4. 查看系統中所有用戶5. 修改用戶對路徑/文件的讀寫權限1. adduser step1: 添加新用戶 sudo adduser username 按照提示輸入新…

網絡游戲服務器架構

網絡游戲一般采用C/S結構&#xff0c;客戶端負責繪制游戲世界的實時畫面&#xff0c;服務器端則負責響應所有客戶端的連接請求和游戲邏輯處理&#xff0c;并控制所有客戶端的畫面繪制&#xff0c;客戶端與服務器通過網絡數據包交互完成每一步游戲邏輯。 網關服務器方式&#x…

leetcode3 無重復字符最長子串

給定一個字符串&#xff0c;請你找出其中不含有重復字符的 最長子串 的長度。 示例 1: 輸入: "abcabcbb" 輸出: 3 解釋: 因為無重復字符的最長子串是 "abc"&#xff0c;所以其長度為 3。 示例 2: 輸入: "bbbbb" 輸出: 1 解釋: 因為無重復字符…

如何正確編寫linux守護進程

1、守護進程&#xff0c;也就是通常說的Daemon進程&#xff0c;是Linux中的后臺服務進程。它是一個生存期較長的進程&#xff0c;通常獨立于控制終端并且周期性地執行某種任務或等待處理某些發生的事件。如果想讓某個進程不因為用戶或終端或其他地變化而受到影響&#xff0c;那…

Linux(6)-命令行的使用,history,shell腳本

命令行的使用,shell腳本1.終端shell,man1.1 Ctrlr--匹配查找歷史命令1.2 history [n] --列出歷史命令1.3&#xff01;--執行歷史命令2.shell 編程2.1 shell腳本2.2 注釋2.3 指明所用的shell2.4 支持函數2.5 使用變量2.6 解析命令行參數2.7 if, for, case, while2.8 shell腳本中…

lua元表的理解

元表概念 &#xff08; Metatable&#xff09;元表由鍵名為 事件 (event) 和其中的值叫作元方法 (metamethod)組成。在lua中每個值都有一個元表。而table和userdata所定義的值允許自定義對應的元表&#xff0c;其他都是用統一的元表。我的理解&#xff0c;元表&#xff0c;其實…

程序以及論文

本人長期承接大學計算機專業的畢業設計和論文的編寫。 主要開發語言C&#xff0c;C &#xff08;windows或linux平臺皆可&#xff09;&#xff0c;php&#xff0c;c#&#xff0c;VC 。 課題內容可以是 管理系統&#xff0c;可以是 網站設計開發 可以是 網絡聊天 可以是 應用…

Github(1)-概覽,初始化倉庫

Github網頁-本地git1.github網頁1.1 主要界面1.1.1github主頁1.1.2倉庫主頁1.1.3 個人頁面1.2 注冊github賬號1.3 新建平臺倉庫2.git-本地倉庫2.1 git本地倉庫的三個區域2.2 創建一個本地倉庫GitHub 本質上是一個代碼托管平臺&#xff0c;它提供的是基于 Git 的代碼托管服務。G…

Lua 協程

Lua里的協程是一個原來沒見過的東西&#xff0c;Python的Gevent也是一個基于coroutine的python網絡開發框架。性能據說很不錯。協同的一個關鍵特征是它可以不斷顛倒調用者與被調用者之間的關系協程和一般多線程的區別是&#xff0c;一般多線程由系統決定該哪個線程執行&#xf…

leetcode16 最接近的三數之和

給定一個包括 n 個整數的數組 nums 和 一個目標值 target。找出 nums 中的三個整數&#xff0c;使得它們的和與 target 最接近。返回這三個數的和。假定每組輸入只存在唯一答案。 例如&#xff0c;給定數組 nums [-1&#xff0c;2&#xff0c;1&#xff0c;-4], 和 target 1…