Linux——關于文本處理四兄弟(cut、awk、sed和grep)

前言

經(jīng)常會用到相關的文本處理命令來查詢信息,有些語法太久沒用就忘了經(jīng)常需要去查資料,于是就想整理一篇文章出來方便自己查看,也希望對各位讀者有所幫助。

一、cut命令

cut命令是一個相對比較簡單的命令,主要用來做文本的切割,和之前介紹過的split命令不同,cut命令是根據(jù)文本內(nèi)容來做切割的,而不是根據(jù)文件大小來進行切割的。

參數(shù) 作用
-f 指定要哪一列的數(shù)據(jù),多列數(shù)據(jù)則用逗號隔開,相連的列可以用中橫線表示比如3-5
-d 指定分隔符,默認情況下cut命令用制表符來進行分隔
-n 顯示行號

我們給一個測試文件,一共有三列數(shù)據(jù),我們希望把第1列和第3列的數(shù)據(jù)提取出來放到一個新的文件里面

Jack Boy 19
Marry Girl 15
John Boy 45
Amy Girl 30

通過觀察我們可以發(fā)現(xiàn)文件是以空格來進行文本分隔的,我們可以通過cut -d " " -f 1,3 cut_test > cut_result.log這個命令來實現(xiàn)
最后輸出結果如下

image.png

注意事項:cut雖然簡單易用,但除了比較簡單的場景外我們用的比較少,原因就是cut只支持單個字符作為分隔符,對于多字符或者不規(guī)則字符分隔的列就很不好用了。比如ps -ef的結果集

二、awk命令

awk是比cut命令更加強大的文本處理工具,不僅體現(xiàn)在文本分割更加靈活,awk還有著強大的文本處理能力。

awk [選項] ‘[BEGIN] 模式或條件 {操作} [END]’ 文件1 文件2...

(一)常用選項
選項 作用
-F 指定分隔符,默認為空白字符
-v var=value 再程序開始前設置變量
(二)內(nèi)置變量
變量名 作用
$0 當前處理行整行的內(nèi)容
$n 當前處理行的第n列
NR 當前處理行的行號
NF 當前處理行的字段數(shù)
FS 輸入字段分隔符(默認為空白字符)
OFS 輸出字段分隔符(默認為空白字符)
FILENAME 當前被處理的文件名
RS 輸出記錄分隔符(默認為換行符)
(三)工作原理
  1. BEGIN 語句塊:在處理任何輸入行之前執(zhí)行,主要用于初始化操作
  2. 處理輸入行:對于每一行輸入,awk 會檢查是否匹配指定的模式或條件,如果匹配,則執(zhí)行相應的操作。
  3. END 語句塊:在處理完所有輸入行之后執(zhí)行,常用于匯總或輸出最終結果。
(四)案例演示
1. 獲取現(xiàn)在所有java進程對應的啟動用戶和進程號

cut命令做不到的切分到這里就順利實現(xiàn)了!

 ps -ef | grep java | awk '{print $1 " " $2}'
2、指定分隔符進行切分

有如下文本,文本內(nèi)容通過aba進行分隔的,我們現(xiàn)在按照aba作為分隔符進行分隔,取第1,2列

JackabaBoyaba19
MarryabaGirlaba15
JohnabaBoyaba45
AmyabaGirlaba30

對應的腳本內(nèi)容如下:

awk -F 'aba' '{print $1 " " $2}' awk_test 
image.png
3、打印文本指定行數(shù)

我們希望分別打印文件中第1,3行和第2-4行到新的文件中,這里節(jié)省一下空間我們就還是沿用cut中的案例

  • 打印文本中的第1行和第3行
awk  'NR==1 || NR==3 {print $0}' awk_test 
image.png
  • 打印文本中的第2-4行
    下面2種語法都可以實現(xiàn)
awk  'NR==1, NR==3 {print $0}' awk_test
awk  '(NR>=1)&&(NR<=3) {print $0}' awk_test      
4、在輸出結果中的前面加入行號打印

這里其實可以結合cut、cat命令來輔助我們做新的行號,不過為了方便演示awk的語法,我們就還是用awk來實現(xiàn)

awk '{print NR " "  $0}' awk_test 
image.png
5、加入標題和結尾

我們可以使用BEGINEND來在所有文本處理前后加一下打印語句,比較多的話是加一下標題,然后在結束的地方加一下結束語或者是做一下統(tǒng)計。我們這里就簡單寫一個用例吧,在處理前后打印一下開始和結束的關鍵字

awk 'BEGIN {print "===START EXECUTE==="} {print $0} END {print "===END==="}' awk_test 
image.png
6、根據(jù)關鍵詞or正則進行過濾

awk在文本過濾上面也是一把好手,我們可以使用/regex/{print}的方式來實現(xiàn)文本過濾,比如說我們希望把性別為女的數(shù)據(jù)給篩選出來,可以有幾種方式來實現(xiàn)

  • 直接通過關鍵字進行匹配
 awk '/Girl/{print $0}' awk_test 
  • 通過條件判斷來實現(xiàn)
awk '$2=="Girl" {print}' awk_test 
7、利用BEGINEND來做統(tǒng)計

我們知道BEGINEND可以分別在文本處理前后做一些事情,那么我們可以利用這個特點來做一下數(shù)據(jù)的統(tǒng)計
比如說下面的文件有商品名和價格

IPhone 3000
T-Shirt 50
Bag 20
Coke 15

我們希望統(tǒng)計出文件的總行數(shù)和所有商品的價格,可以借助BEGIN來設置變量,中間過程來計算變量,END展示結果值

awk 'BEGIN {tP=0;tR=0} {print $0;tR++;tP+=$2} END {print "total Price is " tP " totalRowNum is " tR}' awk_test2
image.png
(五)進階用法
1. 利用akw命令實現(xiàn)分組

awk的功能十分強大,我們甚至可以結合數(shù)組來進行數(shù)據(jù)的分組統(tǒng)計,我們可以看下面這個文件

新華字典 30
我與地壇 15
母豬的產(chǎn)后處理 10
我與地壇 15
新華字典 30
新華字典 30

我們希望統(tǒng)計文件中每種書籍出現(xiàn)的次數(shù),格式為書名 出現(xiàn)次數(shù),并且按出現(xiàn)的次數(shù)從高到低進行展示??梢允褂孟旅娴拿顏韺崿F(xiàn)

 awk '{count[$1]++;} END {for(i in count) {print i " " count[i]}}' awk_test3 | sort -rn -k 2

我們簡單解釋一下這條命令吧

  • count[$1]++創(chuàng)建一個關聯(lián)數(shù)組 count,以每行的第1個字段的值為鍵,并將該鍵的值增加 1。如果鍵不存在,它會自動創(chuàng)建并初始化為 0,然后執(zhí)行增加操作。
  • END {for(i in count) {print i count[i]}}
    for(i in count) 遍歷 count 數(shù)組中的所有鍵。print i " " count[i]:打印每個鍵及其對應的計數(shù),為了展示和方便計算,我們這里順便加了一個空格
  • sort -rn -k 2 這里是用sort命令取第二列作為排序列,-r進行倒序排序,-n指定按數(shù)字大小進行排序
image.png

這里有讀者可能會困惑,數(shù)組的索引值一般不是數(shù)字嗎?這里怎么保證分組的字段名剛好是數(shù)字呢?這個困惑我也有過,后面查詢資料后發(fā)現(xiàn)在awk中數(shù)組的鍵(key)可以是數(shù)字、字符串或者是表達式的結果,不一定非得是數(shù)字。實際上,awk 數(shù)組更像是哈希表(hash table),而不是傳統(tǒng)意義上的數(shù)組,因為它們不是基于索引的,而是基于鍵值對的。

三、sed命令
待補充...
四、grep命令
待補充...

小結

總體來說,cut適合簡單場景的文本切割,復雜的文本不建議使用。grep更適合查日志、在文本中查關鍵字的時候使用。對于提取數(shù)據(jù)或者批量編輯數(shù)據(jù),sedawk則更好用,當然學習成本也更高一些,個人感覺sed更適合編輯匹配到的文本,awk可以配合來做文本切割、文本處理、篩選、統(tǒng)計等這類格式化的操作。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容