shell腳本最常見的一個用途就是處理文本檔案,檢查日志檔案、讀取配置 檔案、處理資料元素,shell腳本可以幫助我們將文本檔案中各種資料的日常處理任務自動化,但僅靠shell腳本命令來處理文本檔案的內容有點力不從心的,如果想在shell腳本中處理任何型別的資料,掌握grep,sed和gawk工具可以達到事半功倍的效果,企業開發中常用,高階命令,
linux文本處理三劍客:grep+sed+awk(gawk)
16.0 grep的使用
所有的類linux系統都會提供一個名為grep(global regular expression print,全域正則運算式輸出)的搜索工具,
grep命令在對一個或多個檔案的內容進行基于模式的搜索的情況下是非常有用的,模式可以是單個字符、多個字符、單個單詞、或者是一個句子,當命令匹配到執行命令時指定的模式時,grep會將包含模式的一行輸出,但是并不對原檔案內容進行修改,一般和管道符|一起使用,
1.0.1grep在單個檔案中查找單詞
grep ds_user /etc/passwd
16.0.2 grep常見的用法
1.grep在多個檔案中查找單詞
grep ds_user /etc/passwd /etc/shadow /etc/gshadow
2.使用-l引數列出包含指定模式的檔案的檔案名,既哪個檔案里這個單詞
grep -l ds_user /etc/passwd /etc/shadow /etc/gshadow
3. 使用-n引數,在檔案中查找指定模式并顯示匹配行的行號
grep -n ds_user /etc/passwd
5. 使用-v引數輸出不包含指定模式的行
grep -v ds_user /etc/passwd
6. 使用 ^ 符號輸出所有以某指定模式開頭的行.,同樣可以使用 $ 符號輸出所有以指定模式結尾的行
grep ^root /etc/passwd
grep bash$ /etc/passwd
7. 使用 -c 引數計算模式匹配到的數量
grep -c bash$ /etc/passwd

16.1 sed編輯器
sed編輯器被稱作流編輯器(stream editor),和普通的互動式文本編輯器恰好相反,在互動式文本編輯器中(比如vim),你可以用鍵盤命令來互動式地插入、洗掉或替換資料中的文本,流編輯器則會在編輯器處理資料之前基于預先提供的一組規則來編輯資料流,
sed編輯器可以根據命令來處理資料流中的資料,這些命令要么從命令列中輸入,要么存盤在一個命令文本檔案中,sed編輯器會執行下列操作,
16.1.1 sed編輯器概述
| sed編輯器執行流程大致如下:
核心原理剖析:
|
16.1.2 sed語法格式
| 1.語法格式: sed options script file 2.常用引數羅列:
注意: script 引數指定了應用于流資料上的單個命令,如果需要用多個命令,要么使用 -e 選項在 命令列中指定,要么使用 -f 選項在單獨的檔案中指定,有大量的命令可用來處理資料, |
16.1.3 sed使用案例
默認情況下, sed 編輯器會將指定的命令應用到 STDIN 輸入流上,這樣你可以直接將資料通過管道輸入 sed 編輯器處理,
1.命令列簡單使用演示
| 1. sed單行文本修改 echo " this is a test " | sed 's/test/big big test/'
注意:sed編輯器中使用了 s 命令, s 命令會用3個斜線間指定的第二個斜線間的文本字串來替換第一個斜線建文本字串模式,前提是能匹配到第一個文本,尤其注意空格的等特殊字符, 2.sed替換文本中資訊輸出 The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. 命令使用:sed 's/dog/and fat cat/' ./sed_demo
特別注意的是:要記住,sed編輯器并不會修改文本檔案的資料,它只會將修改后的資料發送到STDOUT ,如果你查看原來的文本檔案,它仍然保留著原始資料,可以cat查看一下,如果想保存結果直接使用重定向即可,
3. 命令列使用多個編輯器命令 sed -e sed -e 's/brown/green/; s/dog/cat/' ./sed_demo 兩個命令都作用到檔案中的每行資料上,命令之間必須用分號隔開,并且在命令末尾和分號之間不能有空格,這里同時替換輸出兩處,
4.加強版,從檔案中讀取命令,處理文本檔案 如果有大量要處理的 sed 命令,那么將它們放進一個單獨的檔案中通常會更方便一些, 可以在 sed 命令中用 -f 選項來指定檔案,類似于hive腳本執行, vi s.sed 存放sed命令(注意這里可以用加單引號) s/brown/green/ s/fox/elephant/ s/dog/cat/
5.生產案例 hdfs dfs -du -h /user/*/.Trash
hdfs dfs -du -h /user/*/.Trash |awk '{if($2=="T") print$0}'|sort -nrk 1 |
16.2 awk與gawk概述與使用
雖然sed編輯器是非常方便自動修改文本檔案的工具,但其也有自身的限制,通常你需要一個用來處理檔案中的資料的更高級工具,它能提供一個類編程環境來修改和重新組織檔案中的資料,這正是awk/gawk能夠做到的
16.2.1 awk與gawk概述
awk其名稱得自于它的創始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首個字母,實際上 AWK 的確擁有自己的語言: AWK 程式設計語言 , 三位創建者已將它正式定義為“樣式掃描和處理語言”,它允許您創建簡短的程式,這些程式讀取輸入檔案、為資料排序、處理資料、對輸入執行計算以及生成報表,還有無數其他的功能,
awk 是一種很棒的語言,它適合文本處理和報表生成,其語法較為常見,借鑒了某些語言的一些精華,如 C 語言等,在 linux 系統日常處理作業中,發揮很重要的作用,掌握了 awk將會使你的作業變的高大上, awk 是三劍客的老大,利劍出鞘,必會不同凡響,
gawk程式是Unix中的原始awk程式的GNU版本,gawk程式讓流編輯邁上了一個新臺階,他提供了一種編程語言而不只是編輯命令
生產經常給需要排查報錯,查詢日志,但在日志檔案中找出錯誤行會很難,gawk程式可以讓你從日志檔案中過濾出需要的資料元素,然后你可以將其格式化,使得重要的資料更易于閱讀,
gawk的強大之處在于程式腳本,可以寫腳本來讀取文本行的資料,然后處理并顯示資料,創任何型別的輸出報告,
gawk有很多種用法,功能強大,內容很多,先掌味訓礎的,使用時知道怎么查即可,網上很多腳本都是現成的學會檢索,學會修改,創新是幾倍,幾十倍的生產力提升,我們大多數人做的其實就是優化,優化做好了就很膩害了,
16.2.2 awk與gawk的使用
| 1. 標準語法格式 gawk ‘{options }’program file 注意構成 gawk 腳本的陳述句須包含在一對大括號( {} )中,而作為命令選項的整個腳本需要包含在一對引號中, 2.細分語法格式: gawk '{pattern + action}' {filenames} #pattern 表示 AWK 在資料中查找的內容,而 action 是在找到匹配內容時所執行的一系列命令 |
awk作業流程:
- 通過關鍵字 BEGIN 執行 BEGIN 塊的內容,即 BEGIN 后花括號 {} 的內容,
- 完成 BEGIN 塊的執行,開始執行body塊
- 讀入有 \n 換行符分割的記錄,
- 將記錄按指定的域分隔符劃分域,填充域,$0 則表示所有域(即一行內容),$1 表示第一個域,$n 表示第 n 個域,
- 依次執行各 BODY 塊,pattern 部分先匹配該行內容成功后,才會執行 awk-commands 的內容,
- 回圈讀取并執行各行直到檔案結束,完成body塊執行,
- 開始 END 塊執行,END 塊可以輸出最終結果,
尖叫提醒:
- 通常,awk是以檔案的一行為處理單位的,awk每接收檔案的一行,然后執行相應的命令,來處理文本,
- BEGIN開始塊就是在程式啟動的時候執行的代碼部分,并且它在整個程序中只執行一次,一般情況下,我們可以在開始塊中初始化一些變數,BEGIN 是 AWK 的關鍵字,因此它必須是大寫的,注意:開始塊部分是可選的,你的程式可以沒有開始塊部分,
- 主體塊(BODY)對于每一個輸入的行都會執行一次主體部分的命令,默認情況下,對于輸入的每一行,AWK 都會執行命令,但是,我們可以將其限定在指定的模式中,注意:在主體塊部分沒有關鍵字存在,
- 結束塊(END)結束塊是在程式結束時執行的代碼, END 也是 AWK 的關鍵字,它也必須大寫, 與開始塊相似,結束塊也是可選的,
awk的運算子:
gawk常用內置變數:
gawk的語法格式與引數
| 1.gawk使用欄位變數: gawk 會自動地將每行文本中的每個資料欄位賦值給一個指定的變數,默認情況下,預先定義的變數為:(注意:文本行中的資料欄位是通過預先定義的欄位分隔符來分隔開的,默認為空格(包括 TAB ))
案例演示: 0.直接輸出
awk '{ print $0}' ./dbtable_data.txt
注意,當然gawk也支持其他分隔符,-F引數指定如下: gawk -F, '{print $2}' 2.txt
1.gawk對正則的匹配支持 1.1 正則匹配~ 表示模式開始,兩個斜杠// 中是正則匹配模式, 輸出第二列包含 "applist",并列印整行,或者第一第二行 awk -F, '{ print $1 }' dbtable_data.txt awk -F',' '$2 ~ /applist/ { print $1,$2 }' dbtable_data.txt awk -F',' '$2 ~ /device.*applist/ { print $1,$2 }' dbtable_data.txt awk -F',' '$2 ~ /^fin.*applist/ { print $2 }' dbtable_data.txt awk 'BEGIN {FS=","} ;{ print $1 }' dbtable_data.txt 1.2.正則匹配,模式取反,!~ 表示模式開始,// 中是模式, 輸出第二列不包含 "applist",并列印整行,或者第一第二行 awk -F',' '$2 !~ /applist/ { print $1,$2 }' dbtable_data.txt 2.多個命令 gawk 語言允許在腳本陳述句中組合多個命令使用,只需要在各命令之間使用分號( ; )分隔開即可
gawk -F, '{ $2="HELLO";print $2}' dbtable_data.txt
3. 處理前,處理后BEGIN,END 默認情況下,gawk 從輸入中讀取一行文本,再對該文本執行程式指令,而有時候需要在讀取待處理資料之前先執行某些指令,此時就要用到BEGIN關鍵字,同樣的,END 關鍵字允許你指定在資料處理完成后才執行的腳本, awk 'BEGIN{a=5;a+=5;print a}' awk 'BEGIN{a=1;b=2;print (a>2&&b>1,a=1||b>1)}' gawk 'BEGIN {print "我準備開始干活了"}; {print $0}; END {print "活我干完了"}' 2.txt
4.gawk命令通過腳本獲取執行 語法格式:gawk -f 腳本名 檔案名 gawk 允許先將其程式腳本保存在某個檔案中,再通過 -f 選項指定該檔案的檔案名,而在腳本檔案中,各命令不再需要通過 ';' 符號分隔,直接分行列出即可,但是注意需要用{}括起來,
5.gawk匹配檢索 awk -F ',' '{ if($2 =="device_applist_join_full_monthly") print $0}' 000000_0 awk -F ',' '{ if(($2 =="device_applist_join_full_monthly")) print $0}' 注意if判斷可以使用兩個小括號,也可以使用一個,結果一樣
6. gawk其他相關操作(nr,nf等) $ awk -F":" '{ print $1 }' /etc/passwd $ awk -F":" '{ print $1 $3 }' /etc/passwd #沒有分隔,自動拼接字串 $ awk -F":" '{ print $1, $3 }' /etc/passwd #結果空格分隔 $ awk -F":" '{ print $1 " " $3 }' /etc/passwd #空格分隔 $ awk -F":" '{ print "username: " $1 "\t\tuid:" $3}' /etc/passwd
案例1:NR只查看檔案內第20到第30行的內容 awk '{if(NR>=20 && NR<=30) print $1}' table.txt
案例2:NF的使用,列印某行欄位數是N個的行資料 awk -F ":" 'NF==8{print $0}' awk_testdata.txt
|
16.3sed,gawk,grep對比
- grep 更適合單純的查找或匹配文本
- sed 更適合編輯匹配到的文本
- awk 更適合格式化文本,對文本進行較復雜格式處理
16.4 sort排序使用
sort是在Linux里非常常用的一個命令,管排序的,Linux sort 命令用于將文本檔案內容加以排序,sort 可針對文本檔案的內容,以行為單位來排序,
sort其實比較原理簡單粗暴:sort將檔案的每一行作為一個單位,相互比較,比較原則是從首字符向后,依次按ASCII碼值進行比較,最后將他們按升序輸出,
| 1.sort的格式: sort 選項 檔案 2.sort常見的引數
3.案例演示 3.1.sort演示
3.2.sort -u去重排序
3.3 sort -r降序
4.sort排序后資料保存以及sort-n使用
5.指定分隔符以及指定排序-t,-k
|
| 綜合案例: hdfs dfs -du -h /user/*/.Trash |awk '{if($2=="T") print$0}'|sort -nrk 1
|
尖叫總結: linux文本處理內容龐大而繁雜,抓住主線,需要用的時候去查詢,學習不要死記硬背,關鍵是把握方法哈,有些使用需要結合作業場景講解,大家入門學習掌握這些就夠了,其他的需要時百度即可,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/379479.html
標籤:其他






















