文本三劍客指 Linux環境下的?grep(搜索)、sed(編輯)、awk(分析)三款用于文本處理的核心命令,三者分工明確、功能互補,是處理日志、配置文件、結構化數據等場景的 “剛需工具”。
一、grep(文本搜索)
grep命令的核心定位是文本搜索,可以按照“關鍵詞”或“正則表達式”在數據源中進行行過濾,從而檢索到相匹配的行。該命令不修改文本內容,只負責查找內容。
1、命令格式
grep [參數] '<匹配內容>'?[文件名]
2、常見參數
- -i: 不區分大小寫
- -n: 顯示行號
- -r: 逐層遍歷目錄查找
- -v: 查找不包含指定內容的行,反向選擇
- -E:使用擴展正則匹配
- ^key:以關鍵字開頭
- key$:以關鍵字結尾
- ^$:匹配空行
- -w: 按單詞搜索
- -o: 打印匹配關鍵字
- -c: 統計匹配到的次數
- -A: 顯示匹配行及后面多少行
- -B: 顯示匹配行及前面多少行
- -C: 顯示匹配行前后多少行
- -l:只列出匹配的文件名
- -L:列出不匹配的文件名
- -e: 使用正則匹配
3、應用示例
#忽略大小寫匹配包含Error的行
grep -i Error catalog.out#精確匹配Error單詞
grep -w Error catalog.out#打印匹配到的關鍵字Error
grep -wo Error catalog.out#打印匹配到Error關鍵字的行號
grep -n Error catalog.out#忽略大小寫匹配統計包含關鍵字Error的行
grep -ni Error catalog.out#忽略大小寫匹配統計包含關鍵字Error的行數
grep -nic Error catalog.out#忽略大小寫匹配以Error開頭的行
grep -i ^Error catalog.out#匹配以bash結尾的行
grep bash$ /etc/passwd#匹配空行并打印行號
grep -n ^$ /etc/passwd#匹配以#號開頭的行
grep ^# nginx.conf#匹配不以#號開頭的行
grep -v ^# nginx.conf#匹配包含Cause關鍵字及其后5行
grep -A 5 Cause catalog.out#匹配包含Cause關鍵字及其前5行
grep -B 5 Cause catalog.out#匹配包含Cause關鍵字及其前后5行
grep -C 5 Cause catalog.out
二、sed(文本編輯)
sed是一種流文本編輯工具,專注于按照指定規則批量修改文本(如替換字符、刪除、插入等)。編輯文件的時候,會在內存中開辟一塊模式空間(緩存空間),以行為單位將文件內容加載到該空間,并在其中進行內容編輯。編輯完成后會默認在當前終端界面打印內容,然后清空緩存 空間里的內容,再來讀取第二行內容,依次循環。通過制定選項,才會修改原文件。
1、命令格式
sed [參數] '<匹配條件> [動作]' [文件名]
sed -i [替換格式] [文件名]
源數據 | sed -i [替換格式]
2、常見參數
- 空:只展示sed的操作效果,實際上不對文件進行編輯
- -n:不自動打印所有內容
- -e:基于命令實現對文件的多點編輯操作
- -f:從指定文件中讀取編輯文件的“匹配條件+動作”
- -r:支持使用擴展正則表達式
- -i:表示對文件進行編輯
- -i.bak:復制文件原內容到備份文件,然后對原文件編輯
3、常見匹配條件
匹配條件分為兩種:數字行號或者關鍵字匹配
數字行號:
- 空:表示所有行
- n:表示第n行
- $:表示末尾行
- n,m:表示第n到m行內容
- n,+m: 表示第n到n+m行
- ~步進:1~2 表示奇數行,2~2 表示偶數行
關鍵字匹配:
- '/關鍵字/'
4、常見動作
- -a[\text]:在匹配到的內容下一行增加內容,支持\n實現多行追加
- -i[\text]:在匹配到的內容當前行增加內容
- -c[\text]:在匹配到的內容替換內容
- -d|p:刪除|打印匹配到的內容
- -s:替換匹配到的內容
- W /path/somefile:保存模式匹配的行至指定文件
- r /path/somefile:讀取指定文件的文本至模式空間中
- =:為模式空間中的行打印行號
- ! :模式空間中匹配行取反處理
5、常見替換格式
- '行號s/原內容/替換后內容/列號':替換指定匹配的內容
- 's/原內容/替換后內容/':替換每行首個匹配內容
- 's/原內容/替換后內容/g':替換所有匹配的內容
- '行號s/原內容/&新增內容/列號':替換指定的內容(&符號代表源內容,實現的效果是 '原內容+新內容')
- '行號a\新增內容':在指定行號的下一行增加內容
- '行號i\新增內容':在指定行號的當行增加內容
- '行號d':刪除指定行
- '行號c\內容':替換指定行整行內容
- '行號r 文件名':替換文件內容到指定行
- '行號w 文件名':將指定行內容保存到指定文件
6、應用示例
#只打印第2行
sed -n '2p' nginx.log#只打印第1行和第3行
sed -n '1p;3p' nginx.log#只打印包含Error的行
sed -n '/Error/p' nginx.log#只打印奇數行
sed -n '1~2p' nginx.log#只打印偶數行
sed -n '2~2p' nginx.log#只打印第1行和第3行,-e實現多次文件編輯動作
sed -n -e '1p' -e '3p' nginx.log#使用sed_cmd.list文件里的匹配條件和動作去編輯文件
sed -n -f sed_cmd.list nginx.log#取反顯示,輸出除了第2行以外的其他所有行
sed -n '2!p' nginx.log#查看內容屬于第幾行
sed -n '/Error/=' nginx.log#替換每行的第一個匹配上的xmx為Xmx
sed -i 's/xmx/Xmx/' jvm.conf#替換文件中所有的xmx為Xmx
sed -i 's/xmx/Xmx/g' jvm.conf#替換第2行的首個xmx為Xmx
sed -i '2s/xmx/Xmx/#' jvm.conf#替換每行的第2個xmx為Xmx
sed -i 's/xmx/Xmx/2' jvm.conf#替換第3行的第2個xmx為Xmx
sed -i '3s/xmx/Xmx/2' jvm.conf#指定第2行的下一行新增內容test
sed -i '2a\test' jvm.conf#指定1~3行,每行的下一行都增加內容test
sed -i '1,3a\test' jvm.conf#指定第2行新增內容test
sed -i '2i\test' jvm.conf#指定1~3行都增加內容test
sed -i '1,3i\test' jvm.conf#刪除第2行
sed -i '2d' jvm.conf#刪除第1~3行
sed -i '1,3d' jvm.conf#替換第2行內容為test
sed -i '2c\test' jvm.conf#替換第1~3行為1行,內容為test
sed -i '1,3c\test' jvm.conf#將第2行替換為1.txt的文件內容
sed -i '2r 1.txt' jvm.conf#將第2行內容保存到1.txt中
sed -i '2w 1.txt' jvm.conf#將第1~3行內容保存到1.txt中
sed -i '1,4w 1.txt' jvm.conf#查看匹配的內容
sed -n '/send/p' nginx.conf#查看匹配內容到第8行的內容
sed -n '/send/,8p' nginx.conf#查看第1行到匹配行的內容
sed -n '1,/send/p' nginx.conf#查看匹配內容和后三行的內容
sed -n '/send/,+3p' nginx.conf#通過!p去除空行匹配
sed -n '/^$/!p' nginx.conf
三、awk(文本分析)
awk認為文件中的每一行是一條記錄,記錄與記錄的分隔符為換行符,每一列是一個字段,字段與字段的分隔符默認是一個或多個空格或tab制表符。它的工作方式是逐行讀取文本數據,將每一行數據視為一條記錄(record),每條記錄以字段分隔符分成若干字段,然后輸出各個字段的值。然后以查找匹配某個特定模式的文本行,并對這些文本執行制定動作。
簡單來說就是按 “行” 和 “字段” 分割文本(默認空格 / 制表符為分隔符),支持條件判斷、計算、統計,適合處理日志、CSV 等結構化數據。
1、命令格式
awk [參數] '[動作]' [文件名]
awk [參數] –f 動作文件 var=value [文件名]
awk [參數] 'BEGIN段 [動作] END段' [文件名]
- BEGIN: 在開始處理數據流之前執行,可選項
- 動作: 如何處理數據流,必選項
- END: 處理完數據流后執行,可選項
2、常見參數
- -F:指定列的分隔符,默認一行數據的列分隔符是空格
- -f:file 指定讀取程序的文件名
- -v:var=value 自定義變量
3、常見動作
- print:顯示內容
- $0:顯示當前行所有內容
- $n:顯示當前行的第n列內容,如果存在多個$n,它們之間使用逗號隔開
4、常見內置變量
- FILENAME:當前輸入文件的文件名,該變量是只讀的
- NR:指定顯示行的行號
- FNR:多文件時候,分別計數
- NF:表示字段數量
- OFS:輸出格式的列分隔符,缺省是空格
- FS:輸入文件的列分隔符,缺省是連續的空格和Tab
- RS:輸入記錄分隔符,指定輸入時的換行符,原換行符($)仍有效
- ORS:輸出記錄分隔符,輸出時用指定符號代替換行符
- ARGC|ARGV[n]:獲取命令的參數個數|參數內容
5、應用示例
#打印第1列的內容
awk '{print $1}' info.csv#打印第3列內容
awk '{print $3}' info.csv#打印最后一列信息
awk '{print $NF}' info.csv#打印所有內容
awk '{print $0}' info.csv#打印第列和第3列內容
awk '{print $1,$3}' info.csv#打印信息時候,合并信息
awk '{print $1$3}' info.csv#使用\t實現內容的分割,需要用""擴住
awk '{print $1"\t"$3}' info.csv#打印指定的內容
awk '{print "hello awk"}' info.csv#打印每列的行號
awk '{print NR,$0}' info.csv#按照行號打印對應列的內容
awk '{print NR, $NR}' info.csv#指定行號打印信息
awk 'NR==1 {print NR,$1,$3}' info.csv#以逗號為列分隔符,打印第2列
awk -F ',' '{print $2}' info.csv
awk -v FS="," '{print $2}' info.csv#以冒號為列分隔符,打印第1列和第2列
awk -F ',' -v OFS=":" '{print $1,$2}' info.csv
awk -F"," 'BEGIN{OFS=":"} {print $1,$7}' info.csv#在BEGIN內部同時實現多個環境變量
awk 'BEGIN{-F",";OFS=":"} {print $1,$7}' info.csv#設置變量,字符串賦值并輸出變量值
awk 'BEGIN{name="test";print name}'#設置變量,數字賦值并輸出變量值
awk 'BEGIN{i=10;print i+=1}'#數值運算
awk 'BEGIN{print 100+3}'
awk 'BEGIN{print 100*3}'
awk 'BEGIN{print 100/3}'#邏輯運算(輸出真假,即1、0)
awk 'BEGIN{print 100>=2 && 100>=3 }'
awk 'BEGIN{print 100>=2 && 1>=100 }'
awk 'BEGIN{print 100>=2 || 1>=100 }'
awk 'BEGIN{print 100>=200 || 1>=100 }'#文件參與的邏輯運算,輸出uid為0或大于1000的用戶名
awk -F: '$3==0 || $3>=1000 {print $1}' /etc/passwd
附:正則表達式
在 Linux 中,正則表達式(Regular Expression,簡稱 regex)是一種用于 模式匹配與文本過濾 的工具,廣泛結合 grep、sed、awk 等文本處理命令使用,用于精準查找、替換或提取符合規則的字符串。
1、正則表達式的分類(Linux 中核心兩類)
Linux 工具對正則表達式的支持分為 基礎正則表達式(BRE) 和 擴展正則表達式(ERE),主要區別在于對部分元字符的支持是否需要轉義:
- 基礎正則(BRE):grep(默認)、sed(默認)等工具支持,部分元字符(如 +、?、|)需要用 \ 轉義才能生效。
- 擴展正則(ERE):grep -E(或 egrep)、sed -r、awk 等工具支持,元字符無需轉義,直接使用。
2、常用基礎元字符與示例(BRE 和 ERE 通用,無需轉義)
元字符 | 作用 | 示例 |
^ | 匹配行首(以指定字符開頭的行) | grep "^root" /etc/passwd?→ 匹配以?root?開頭的行 |
$ | 匹配行尾(以指定字符結尾的行) | grep "bash$" /etc/passwd?→ 匹配以?bash?結尾的行 |
. | 匹配任意單個字符(除換行符) | grep "r..t" /etc/passwd?→ 匹配?r?開頭、t?結尾,中間 2 個任意字符的字符串(如?root、rxtt) |
* | 匹配前面的字符?0 次或多次 | grep "ro*ot" test.txt?→ 匹配?r?后接任意個?o?再跟?ot(如?rot、root、rooot) |
[] | 匹配字符集中的任意一個字符 | grep "[0-9]" test.txt?→ 匹配包含數字的行;grep "[a-zA-Z]"?→ 匹配包含字母的行 |
[^] | 匹配?不在?字符集中的任意一個字符(取反) | grep "[^0-9]" test.txt?→ 匹配不包含數字的行;grep "^[^#]" config.conf?→ 匹配非注釋行(非?#?開頭) |
\ | 轉義字符(將特殊字符視為普通字符) | grep "a\*b" test.txt?→ 匹配字符串?a*b(*?被轉義為普通字符) |
3、常用擴展元字符(ERE 直接用,BRE 需轉義為?\+
、\?
?等)
元字符 | 作用 | 示例(以 ERE 為例) |
+ | 匹配前面的字符?1 次或多次 | grep -E "ro+ot" test.txt?→ 匹配?r?后接至少 1 個?o?再跟?ot(如?root、rooot,不匹配?rot) |
? | 匹配前面的字符?0 次或 1 次 | grep -E "ro?ot" test.txt?→ 匹配?r?后接 0 個或 1 個?o?再跟?ot(如?rot、root,不匹配?rooot) |
() | 分組(將多個字符視為一個整體) | grep -E "(ab)+" test.txt?→ 匹配?ab?連續出現 1 次或多次(如?ab、abab) |
` | ` | 邏輯 “或”(匹配多個模式中的一個) |
{n} | 匹配前面的字符?恰好 n 次 | grep -E "o{2}" test.txt?→ 匹配包含連續 2 個?o?的字符串(如?oo、root?中的?oo) |
{n,} | 匹配前面的字符?至少 n 次 | grep -E "o{2,}" test.txt?→ 匹配包含連續 2 個及以上?o?的字符串(如?oo、ooo) |
4、不同工具中的正則使用差異
- grep:默認使用 BRE,擴展元字符需轉義(如?grep "ro\+ot"),加?-E?選項啟用 ERE(如 grep -E "ro+ot"),無需轉義。
- sed:默認使用 BRE(如?sed 's/ro\+ot/xxx/'),加?-r?選項啟用 ERE(如?sed -r 's/ro+ot/xxx/')。
- awk:本身支持 ERE,無需轉義(如?awk '/ro+ot/' test.txt)。