Linux三劍客grep、awk和sed

測試開發小記發表於2021-01-19

grep,sed 和 awk是Linux/Unix 系統中常用的三個文字處理的命令列工具,稱為文字處理三劍客。本文將簡要介紹這三個命令並給出基本用法。

管道

在介紹這兩個命令之前,有必要介紹一下Unix/Linux中管道(pipe)的概念。管道將一個命令/程式/程式的輸出傳送到另一個命令/程式/程式,以進行進一步處理。是一種程式間通訊機制,使用管道符"|”將兩個命令隔開,管道符左邊命令的輸出就會作為管道符右邊命令的輸入。

管道實現了資料在多個命令之間傳遞,不需要建立臨時檔案來傳遞,它是單向的,資料通過管道從左向右流動。

例項1:
cat test.txt | grep test1

# cat test.txt | grep test1
test1
test111
test3 test1
test111
# cat test.txt | grep test1 | grep test3
test3 test1
#

例項2:

# cat test.txt | head -3
test1
test2
test3
# cat test.txt | tail -5
test
test

test
rrrr
# 

grep

定義

grep(Global Regular Expression Print) 命令用於搜尋檔案的特定模式,它不能增加、修改、刪除文字內容,通常用於搜尋過濾文字,顯示被模式匹配到的行。使用正規表示式進行文字匹配(正規表示式參考文章《Python正規表示式》),它的使用許可權是所有使用者。

命令形式:
grep [OPTIONS] PATTERN [FILE...]
擴充套件正規表示式(rgrep)新增 -E 引數:
grep -E [OPTIONS] PATTERN [FILE...]

選項引數

  • -v 或 --invert-match : 顯示不被 pattern匹配到的行
  • -n 或 --line-number : 顯示匹配的行號
  • -o 或 --only-matching :僅顯示匹配到的字串
  • -c 或 --count : 統計匹配的行數
  • -i 或 --ignore-case :忽略字元大小寫
  • -m或--max-count:-m 1 ,匹配到1行後停止匹配
  • -A<顯示行數> 或 --after-context=<顯示行數> : 除了顯示符合範本樣式的那一列之外,並顯示該行之後的內容。
  • -B<顯示行數> 或 --before-context=<顯示行數> : 除了顯示符合樣式的那一行之外,並顯示該行之前的內容。

例項1:查詢檔案內容,顯示行號

查詢檔案內容包含'test1'的行,顯示行數

# grep -n test1 test.txt 
1:test1
7:test111
9:test3 test1
11:test111
# grep -o test1 test.txt  
test1
test1
test1
test1
# grep -no test1 test.txt
1:test1
7:test1
9:test1
11:test1

例項2:查詢檔案內容,不包含test1的行

# grep -nv test1 test.txt
2:test2
3:test3
4:test4
5:test5
6:test6
8:test2
10:test

例項3:grep 正規表示式

查詢test1開頭的行

# grep -n ^test1 test.txt
1:test1
7:test111
11:test111

查詢以1結尾的行

# grep -n 1$ test.txt    
1:test1
7:test111
9:test3 test1
11:test111

檢視程式

# ps -aux | grep chrome
root       5425  0.4  1.8 869280 34200 pts/0    Sl   Dec22  11:31 /opt/google/chrome/chrome --no-sandbox
root       5439  0.0  0.0 563592  1132 pts/0    S    Dec22   0:00 /opt/google/chrome/chrome --type=zygote --no-zygote-sandbox --no-sandbox
root       5440  0.0  0.1 563592  2836 pts/0    S    Dec22   0:06 /opt/google/chrome/chrome --type=zygote --no-sandbox
root       5441  0.0  0.0  26452   208 pts/0    S    Dec22   0:00 /opt/google/chrome/nacl_helper --no-sandbox
root       5442  0.0  0.0  26452   144 pts/0    S    Dec22   0:00 /opt/google/chrome/nacl_helper --no-sandbox

sed

定義

sed(Stream Editor)是一種流編輯器,一次處理一行內容,將行儲存在模式空間(臨時緩衝區),然後用sed命令處理模式空間中的內容,處理完成後將內容送入螢幕,然後清除模式空間,繼續讀入下一行,執行下一個迴圈,直到檔案末尾。這個過程中不會改變檔案內容(除了 -i 選項)。

命令形式:
sed [選項] [sed命令] [-f <script FILE>] [FILE]
檢視幫助文件:

man sed
sed -h

選項

  • -h: 顯示幫助資訊
  • -n: 僅顯示 script處理後的結果,常與sed命令p連用:sed -n 'p' test.txt 列印test.txt檔案內容
  • -e:直接在指令列模式上進行 sed 的動作編輯,不修改原檔案,輸出到終端
  • -i:修改檔案內容,而不輸出到終端
  • -f filename : sed 動作寫在filename 內,執行 filename 內的sed 動作
  • -r∶擴充套件正規表示式

常用命令

  • a:append,新增: sed -e '4 a newline' test.txt
  • c:change,取代: sed -e '2,5c No 2-5 number' test.txt
  • d:delete,刪除: sed -e '2,5d' test.txt
    • sed '/^$/d' test.txt:刪除test.txt檔案空行
  • i:insert,插入: sed -e '2i newline' test.txt
  • p:print,列印:sed -n 'p' test.txt
  • s:substitute,替換: sed -e 's/old/new/g' test.txt
    • sed 's/$/%/' test.txt:在每行末尾新增%
    • sed s/ *//g test.txt: 刪除test.txt檔案空格
  • N:將下一行新增到pattern space中,將當前讀入行和用N命令新增的下一行看成“一行”

注意在替換操作中,替換時用的分割符 '/' 可以使用其它符號代替,特別是替換的內容中有 '/' 時,可以使用@、#、%等符號代替。

例項1:列印並輸出資料

列印並輸出第5行資料

# sed -n '5p' test.txt
test5
# cat -n test.txt | sed -n '5p' 
     5	test5
# 

列印並輸出第3-5行資料

# sed -n '3,5p' test.txt
test3
test4
test5

取反,不選擇第3到5行資料

# sed -n '3,5!p' test.txt
test1
test2

隔行輸出

# sed -n '1~2p' test.txt
test1
test3
test5
# sed -n '1~3p' test.txt
test1
test4
# 

例項2:將匹配的行資料輸出到指定檔案

# 累加
sed -n '1~2p' test.txt >> a.log
# 覆蓋
sed -n '1~3p' test.txt > a.log 
# sed -n '1~2p' test.txt>> a.log
# cat a.log
test1
test3
test5
# sed -n '1~3p' test.txt > a.log 
# cat a.log
test1
test4
# 

例項3:新增、插入字串

在第2行後加上 newLine

# sed '2 a newline' test.txt
test1
test2
newline
test3
test4
test5
# 

在第2行前加上 newline

# sed '2 i newline' test.txt
test1
newline
test2
test3
test4
test5

例項4:全域性替換

將所有的test2替換為test222

# sed -e 's/test2/test222/g' test.txt
test1
test222
test3
test4
test5
# sed -e 's/test2/test222/' test.txt
test1
test222
test3
test4
test5

例項5:修改檔案

前面的新增、替換操作都沒有改變檔案內容,如果要使檔案修改生效,需要使用 -i 選項。

# sed -i 's/test2/test222/' test.txt
# cat test.txt 
test1
test222
test3
test4
test5
# 

awk

定義

awk是一種文字模式掃描和處理的程式語言,由 Aho, Weinberger 和 Kernighan開發。awk功能強大,可用於資料提取和統計,常用在shell指令碼中。awk逐行讀入檔案,以空格為預設分隔符將每行切片,切開的部分再進行後續處理。

命令形式:
awk [options] 'pattern action' [FILE(s)]

  • pattern:正規表示式
  • action:對匹配到的內容執行的命令(預設為輸出每行內容)

常用引數

  • $0: 整條記錄(當前行)
  • $1 - $n: 表示當前行的第n個域
  • FILENAME: awk瀏覽的檔名
  • BEGIN: 處理文字之前要執行的操作
  • END: 處理文字之後要執行的操作
  • FS: 設定輸入域分隔符,等價於命令列 -F 選項,預設為空格“ ”
    • awk -F: '{print $1}' test.txt
    • 或者 awk 'BEGIN {FS = ":"} {print $1}' test.txt
  • NF: 瀏覽記錄的域的個數/列數
  • NR: 已讀的記錄數/行數
  • FNR: 當前輸入檔案的記錄數
  • OFS: 輸出域分隔符,預設為空格“ ”
  • ORS: 輸出記錄分隔符,預設為“\n”
  • RS: 控制記錄分隔符
  • exit:匹配到第一行內容後退出:awk -F: '{print $2;exit}' test.txt ,grep使用 -m 引數

例項1:查詢、列印

搜尋/etc/passwd有root關鍵字的所有行

# awk -F : '/root/ {print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
#
# awk -F : '/root/ {print $7}' /etc/passwd
/bin/bash
/sbin/nologin

列印etc/passwd/的第二行資訊

# awk -F : 'NR==2 {print $0}' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
#

例項2:BEGIN、END製表

使用 begin加入標題

[root@iZ8vb54310gt89j8qct198Z tmp]# awk -F : 'BEGIN {print "No", "User", "Auth"} {print NR "|" $1 "|" $2} END {print FILENAME}' /etc/passwd
No User Auth
1|root|x
2|bin|x
3|daemon|x
4|adm|x
5|lp|x
6|sync|x
7|shutdown|x
8|halt|x
9|mail|x
.................
28|nscd|x
29|exim|x
/etc/passwd

例項3:自定義分割符

# echo "123|456|789"
123|456|789
# echo "123|456|789" | awk 'BEGIN{RS="|"}{print $0}'
123
456
789
--THE END--

文章標題:Linux三劍客grep、awk和sed
本文作者:hiyo
本文連結:https://www.cnblogs.com/hiyong/p/14238392.html
歡迎關注公眾號:「測試開發小記」及時接收最新技術文章!

相關文章