1. 總覽
grep
、sed
和awk
被稱為Linux三劍客,是因為它們在文本處理和數據操作方面極其強大且常用。
Linux三劍客在文件處理中的作用:
grep(數據查找定位):文本搜索工具,在文件中搜索符合正則表達式的文本內容,并打印匹配的行。
awk(數據切片):文本處理工具,主要用于對結構化數據進行格式化和拆分處理,進行數據統計和報告生成;
sed(數據修改):流編輯器,對文本進行插入、刪除、替換、提取等操作;
2. grep
grep
是一個用于文本搜索的工具,可以在文件中搜索符合正則表達式的文本內容,并打印匹配的行。它簡單、快速,是進行文本搜索和過濾的首選工具。
grep工具的功能:
文本模式搜索
正則表達式匹配
高亮顯示匹配內容
支持遞歸搜索目錄
2.1 基本格式
grep [選項參數] pattern [file...]
參數說明:
1)pattern:過濾條件,可以是正則表達式;
2)file:要搜索的文件(一個或多個),若不指定文件,grep
會從標準輸入讀取。
3)常用選項參數:
參數 | 說明 |
---|---|
-i | 不區分大小寫 |
-v | 排除匹配結果 |
-r 或 -R | 遞歸搜索目錄下的所有文件 |
-l | 僅顯示包含匹配模式的文件名 |
-L | 僅顯示不包含匹配模式的文件名 |
-n | 顯示匹配行與行號 |
-c | 只統計匹配的行數 |
-o | 只輸出匹配到的內容 |
-w | 只匹配過濾到的單詞 |
-A num | 顯示匹配行及之后的 num 行 |
-B num | 顯示匹配行及之前的 num 行 |
-C num | 顯示匹配行及前后各 num 行 |
-E | 使用擴展正則表達式(等同于 egrep ) |
-F | 使用固定字符串模式(等同于 fgrep ) |
-P | 使用 Perl 正則表達式 |
4)grep中正則表達式字符集整理:
-
普通字符:匹配自身。例如,
grep 'a' file.txt
匹配文件中所有包含字符a
的行。 -
點(.):匹配任意單個字符(除換行符外)。例如,
grep 'a.c' file.txt
匹配a
和c
之間有一個字符的行。 - 字符集([...]):
-
[abc]:匹配字符
a
、b
或c
中的任意一個。 -
[^abc]:匹配除
a
、b
和c
之外的任意字符。 -
[a-z]:匹配從
a
到z
的任意字符(包括范圍內的字符)。
-
- 錨點(^ 和 $):
-
^:匹配行首。例如,
grep '^a' file.txt
匹配以a
開頭的行。 -
$:匹配行尾。例如,
grep 'a$' file.txt
匹配以a
結尾的行。
-
-
轉義字符(\):用來轉義元字符,使其失去特殊含義。例如,
grep '\.' file.txt
匹配包含.
字符的行
擴展正則表達式字符集(使用 grep -E
或 egrep
):
-
|:邏輯或,匹配左右任意一個表達式。例如,
grep -E 'a|b' file.txt
匹配包含a
或b
的行 -
():用于分組。例如,
grep -E '(abc|def)' file.txt
匹配包含abc
或def
的行。 -
?:匹配前面的字符 0 次或 1 次。例如,
grep -E 'colou?r' file.txt
匹配color
或colour
。 -
*:匹配前面的字符 0 次或多次。例如,
grep -E 'ab*c' file.txt
匹配ac
、abc
、abbc
等 -
+:匹配前面的字符 1 次或多次。例如,
grep -E 'ab+c' file.txt
匹配abc
、abbc
等。 -
{}:{n}表示匹配前面的字符恰好 n 次;{n,}表示匹配前面的字符至少 n 次;{n,m}表示匹配前面的字符至少 n 次,至多 m 次。
2.2 常用命令舉例
假設有一個file.txt文件,內容如下:
name,age,sex,salary
Alice,30,女,9000
Bob,25,男,8000
Carol,35,男,7000
Karry,21,女,5000
Ross,40,女,6500
Joan,38,男,10000
Linda,46,女,5000
Lily,26,女,3000
KARRY,27,女,6000
1. 基本搜索
#?搜索文件?file.txt?中包含?karry?的行
grep?"Karry"?file.txt
2. 忽略大小寫
#?搜索文件?file.txt?中包含?karry(不區分大小寫)的行。
grep?-i?"karry"?file.txt
3. 遞歸搜索目錄
#?遞歸搜索目錄?/path/to/directory?中所有文件,查找包含?pattern?的行
grep?-r?"Karry"?/opt/
4. 顯示匹配行號
#?搜索文件?file.txt?中包含?karry?的行,并顯示匹配行號
grep?-n?"Karry"?file.txt
5. 僅顯示匹配文件名
#?搜索當前目錄下所有?`.txt`?文件,顯示包含?`pattern`?的文件名。
grep?-l?"Karry"?*.txt
6. 反向匹配
#?搜索文件?`file.txt`?中不包含?`pattern`?的行。
grep?-v?"Karry"?file.txt
7. 顯示匹配行及之后的行
#?搜索文件?`file.txt`?中包含?`pattern`?的行,并顯示匹配行及之后的?3?行。
grep?-A?3?"Karry"?file.txt
8. 顯示匹配行及之前的行
#?搜索文件?`file.txt`?中包含?`pattern`?的行,并顯示匹配行及之前的?3?行
grep?-B?3?"Karry"?file.txt
9. 顯示匹配行及前后行
#?搜索文件?`file.txt`?中包含?`pattern`?的行,并顯示匹配行及前后各?3?行。
grep?-C?3?"Karry"?file.txt
10. 使用擴展正則表達式
#?搜索文件?`file.txt`?中包含?`Ka`?或?`Bo`?的行。
grep?-E?"Ka|Bo"?file.txt
11. 匹配整個單詞
#?搜索文件?`file.txt`?中包含整個單詞?`word`?的行。
grep?-w?"Karry"?file.txt
12. 僅顯示匹配的部分
#?搜索文件?`file.txt`?中的?`Karry`?并僅顯示匹配的部分。
grep?-o?"Karry"?file.txt
3. awk
awk
是一個強大的文本處理工具,主要用于對結構化數據進行模式掃描和處理,有著強大的文本格式化能力。它支持復雜的操作和腳本編寫,能夠進行模式匹配、文本處理、數據報告生成等。
awk功能:
字符串處理和替換;
數據統計和報告生成;
復雜的條件判斷和循環處理;
數據格式轉換。
3.1 基本格式
awk [選項參數] 'pattern { action }' file
參數說明:
1)pattern
:匹配的模式,支持正則表達式。
2)action
:在匹配模式的行上執行的操作。
3)常用選項參數:
參數 | 說明 |
---|---|
-F fs | 指定輸入字段分隔符,默認是空格或制表符 |
-v var=value | 為awk 程序中的變量賦初值 |
-f program-file | 從指定文件讀取awk 程序 |
4)常見的內置變量
內置變量 | 說明 |
---|---|
$0 | 表示完整的輸入記錄 |
$n | 表示指定分隔符后,當前指定的第n個字段 |
FS | 表示字段輸入分隔符,默認以空格為分隔符 |
OFS | 表示字段輸出分隔符 |
NF | 表示字段的個數,即以分隔符分割后,當前行一共有多少個字段 |
NR | 表示當前記錄數,即行數 |
3.2 常用命令舉例
假設有一個file.txt文件,內容如下:
name,age,sex,salary
Alice,30,女,9000
Bob,25,男,8000
Carol,35,男,7000
Karry,21,女,5000
1.基本示例
#?打印文件file.txt的每一行
awk?'{?print?}'?file.txt
2.指定字段分隔符
假設文件內容用逗號分隔,打印第1、第3個字段。(其中 -F ',' 可以直接簡寫成-F,)
awk?-F?','?'{?print?$1,?$3?}'?file.txt
3.使用模式匹配
#?打印包含“Karry”字符串的行
awk?'/Karry/?{?print?}'?file.txt
4.按條件過濾
#?打印第2列字段(age)大于30的人的姓名
awk?-F?','?'$2?>?30?{?print?$1?}'?file.txt
5.使用變量
#?為變量age賦值并使用
awk?-F?','?-v?age=30?'$2?>?age?{?print?$0?}'?file.txt
6.BEGIN和END塊
BEGIN
塊在處理任何輸入行之前執行。
END
塊在處理完所有輸入行后執行。
#?計算file.txt文件中第4列字段(工資)的總和
awk?-F?','?'BEGIN?{?sum=0?}?{?sum?+=?$4?}?END?{?print?sum?}'?file.txt
7.使用-f
選項從腳本文件中讀取程序
1)創建一個名為script.awk
腳本文件
vim??script.awk
并將以下內容寫入腳本文件中:
#!/usr/bin/awk?-f#?使用逗號作為字段分隔符
BEGIN?{?FS?=?","?}#?打印第1和第3字段
{?print?$1,?$3?}
詳細說明:
腳本文件頭部:
#!/usr/bin/awk -f
指定用awk
解釋器來運行這個腳本文件。BEGIN 塊:
BEGIN { FS = "," }
設置字段分隔符為逗號(,
)。主代碼塊:
{ print $1, $3 }
打印每行的第1和第3字段。
保存文件并關閉編輯器 :wq!
2)運行awk腳本文件(有兩種方式) 方式一:直接用 awk
命令來執行這個腳本
awk?-f?script.awk?file.txt
方式二:授權腳本文件具有可執行權限,然后運行腳本文件
#?確保腳本文件具有可執行權限:
chmod?+x?script.awk#運行腳本文件,并指定輸入文件:
./script.awk?file.txt
8. 格式轉換
#?將file.txt文件格式轉換為TSV(Tab?Separated?Values)格式
awk?'BEGIN?{?FS=",";?OFS="\t"?}?{?$1=$1;?print?}'?file.txt
說明:
BEGIN { FS=","; OFS="\t" }
:在處理開始時,將輸入字段分隔符設置為逗號,將輸出字段分隔符設置為制表符。
$1=$1; print
:通過賦值操作強制awk
重新解析字段,然后輸出。
9.提取并格式化指定列
#?假設想提取?`Name`?和?`Age`?列,并格式化輸出為?"Name:?Age?years?old"
awk?-F?','?'{?print?"Name:?"?$1?",?Age:?"?$2?"?years?old"?}'?file.txt
10.轉換為JSON格式
將file.txt文件轉換為JSON格式:
awk?-F,?'NR==1?{for?(i=1;?i<=NF;?i++)?header[i]=$i;next
}?{printf("{");for?(i=1;?i<=NF;?i++)?{printf("\"%s\":\"%s\"",?header[i],?$i);if?(i<NF)?printf(",?");}printf("}\n");
}'?file.txt
11.轉換為HTML表格
將file.txt轉換為HTML表格:
awk?-F,?'BEGIN?{print?"<table?border=\"1\">";print?"<tr><th>Name</th><th>Age</th><th>Gender</th></tr>";
}?
NR>1?{printf("<tr>");for?(i=1;?i<=NF;?i++)?printf("<td>%s</td>",?$i);printf("</tr>\n");
}?
END?{print?"</table>"
}'?file.txt
4. sed
sed
是一個流編輯器,主要用于對文本進行非交互式編輯。它可以進行插入、刪除、替換、提取等操作,是文本處理和轉換的利器。
功能:
文本替換和刪除;
模式匹配和文本插入;
支持腳本編寫進行復雜的文本處理;
數據流操作。
4.1 基本格式
sed [選項參數] 'script' [file]
參數說明:
1)script:sed 內置的命令字符。主要是用于對文件進行增刪改查等操作。
常見內置命令字符:
a:表示對文本進行追加操作,在指定行后面添加一行或多行文本;
d:表示刪除匹配行;
i:表示插入文本,在指定行前添加一行或多行文本;
p:表示打印匹配行內容,通常與-n一同使用;
s/正則/替換內容/g:表示匹配正則內容,然后替換內容(支持正則表達式),結尾g表示全局匹配;
2)file:要處理的輸入文件。若不指定文件,sed
會從標準輸入讀取。
3)常用選項參數:
常見選項參數 | 說明 |
---|---|
-n | 表示取消默認的sed輸出,通常與sed內置命令p一起使用 |
-e script | 直接在命令行上添加要執行的sed 腳本 |
-f script-file | 從腳本文件中讀取sed 命令 |
-i [SUFFIX] | 直接修改文件內容,而不是輸出到標準輸出。可以選擇性地備份文件。如果不加-i,sed修改的是內存數據。 |
-r | 使用擴展正則表達式 |
s | 將文件視為獨立的文件,而不是單一的流 |
4.2 常用命令舉例
假設有一個file.txt文件,內容如下:
name,age,sex,salary
Alice,30,女,9000
Karry,21,女,5000
Joan,38,男,10000
Lily,26,女,3000
KARRY,27,女,6000
1. 文本替換
#?基本替換:將`file.txt`中的第一個匹配`Karry`的字符串替換為`Bob`
sed?'s/Karry/Bob/'?file.txt#?忽略大小寫替換:將`file.txt`中的所有匹配`Karry`的字符串替換為`Bob`
sed?'s/Karry/Bob/Ig'?file.txt#?全局替換:將`file.txt`中的所有匹配`Lily`的字符串替換為`karry`
sed?'s/Lily/karry/g'?file.txt#?指定行替換:將`file.txt`中的第4行中匹配`Joan`的字符串替換為`Carol`
sed?'4s/Joan/Carol/'?file.txt#?行號范圍替換:將`file.txt`中的第3到第6行中匹配`KARRY`的字符串替換為`karry`
sed?'3,6s/KARRY/karry/Ig'?file.txt
使用 sed
進行文本替換時,默認情況下,sed
只是將替換后的文本輸出到標準輸出(通常是終端),而不會直接修改源文件。只有使用-i
參數進行替換,會修改源文件。
#?替換源文件內容:直接在`file.txt`中替換所有匹配`Karry`的字符串為`Bob`,并保存修改(修改源文件)
sed?-i?'s/Karry/Bob/g'?file.txt#備份原始文件,使用`-i`參數加上備份擴展名來實現,進行替換操作之前會創建一個`file.txt.bak`備份文件
sed?-i.bak?'s/Karry/Bob/g'?file.txt
2. 文本刪除
#?刪除某行:刪除`file.txt`中的第5行
sed?'3d'?file.txt#?行號范圍刪除:刪除`file.txt`中的第2到第4行。
sed?'3,4d'?file.txt
3. 文本插入
#?插入行:在`file.txt`中的第2行之前插入`This?is?a?new?line.`
sed?'2i\This?is?a?new?line.'?file.txt#?追加行:在`file.txt`中的第3行之后追加`This?is?a?new?line.`
sed?'3a\This?is?a?new?line.'?file.txt
4. 打印模糊匹配行
#?只打印`file.txt`中包含`ka`的行
sed?-n?'/ka/p'?file.txt
5. 從文件讀取腳本
1)創建一個 sed
腳本文件
vim?`script.sed`
并將以下內容寫入腳本文件中:
3a\
This?is?a?new?line.
2)使用 sed
執行腳本文件 使用 sed
命令并指定 -f
選項來讀取和執行 script.sed
文件中的命令:
sed?-f?script.sed?file.txt
5. 與管道結合使用
Linux三劍客grep
、awk
和sed
是文本處理的強大工具,經常與管道( | )結合使用,能進行復雜的文本操作和數據處理。用管道符( | )連接,表示將前一個命令的輸出作為下一個命令的輸入。
假設有一個日志文件file.log
,內容如下:
2023-06-25?12:34:56?info?User1?logged?in
#?連接數據庫失敗
2023-06-25?12:35:00?error?Failed?to?connect?to?database
2023-06-25?12:35:05?info?User2?logged?out
2023-06-25?12:36:10?warn?Disk?space?low2023-06-25?12:36:15?info?User3?logged?in
2023-06-25?12:37:00?error?Time?out
5.1 查找并替換文件中的文本
使用 grep
查找特定的文本行,用 sed
替換:
#?查找包含?`error`?的行并將?`error`?替換為?`warning`
grep?'error'?file.log?|?sed?'s/error/warning/g'
5.2 統計日志文件中特定模式的出現次數
使用 grep
查找特定模式,然后用 wc
統計行數:
#?統計?`file.log`?中?`error`?的出現次數:
grep?'error'?file.log?|?wc?-l
5.3 過濾空行和注釋行后顯示文件內容
使用 grep
和 sed
去除空行和注釋行:
grep?-v?'^#'?file.log?|?sed?'/^$/d'
命令拆解:
1)
grep -v '^#' file.log
:grep用于文件中搜索匹配行;-v
表示反轉匹配,即選出不匹配指定模式的行。'^#'
表示匹配以#
開頭的行;2)
sed '/^$/d'
:sed用于逐行處理文本;/^$/
是正則表達式,匹配空行(行首緊跟行尾,即行中沒有任何字符);d
表示刪除命令,表示刪除匹配的行。
5.4 組合命令過濾并格式化輸出
使用 grep
過濾日志,awk
格式化輸出:
#?從日志文件中提取?`ERROR`?行,并顯示時間和錯誤信息:
grep?'error'?file.log?|?awk?'{print?$1,?$2,?$3,?$5}'
5.5 對文件中的數值列進行排序和去重
使用 awk
提取數值列,sort
排序,uniq
去重:
awk?'{print?$2}'?file.log?|?sort?-n?|?uniq
命令拆解:
1)
awk '{print $2}' file.log
:打印 file.log 文件每行的第2個字段,awk默認是空格或制表符作為分隔符;2)
sort -n
:將上一步輸出的數據按數值排序。sort命令用于對文本行進行排序,-n
選項表示按數值進行排序。3)
uniq
: 移除相鄰的重復行,輸出唯一的行。只有在相鄰行重復時,uniq
才會去重,因此通常與sort
結合使用。
5.6 統計日志文件中每種日志級的出現次數
awk?'{count[$3]++}?END?{for?(level?in?count)?print?level,?count[level]}'?file.log
命令解析:
1)
{count[$3]++}
:awk的主處理塊,在讀取文件的每一行時執行,遇到相同的第三列值時,對應的計數器
count[$3]` 自增 1。2)
END {for (level in count) print level, count[level]}
:awk
的結束塊,在處理完所有行后執行。for循環遍歷count
數組中的所有鍵,打印每個鍵(即第三列的值)及其對應的計數器值(即出現次數)。
5.7 grep、awk、sed三者結合使用
篩選日志文件 file.log
中包含"error"的行,并從中提取出時間戳和錯誤信息,然后進行一些格式化處理:
grep?"ERROR"?log.txt?|?awk?'{print?$1,?$2,?$5}'?|?sed?'s/\[//g;?s/\]//g'
命令解析:
grep "ERROR" log.txt
:篩選出包含 "ERROR" 的行。
awk '{print $1, $2, $5}'
:提取每行的第1列、第2列和第5列。
sed 's/\[//g; s/\]//g'
:刪除方括號。
5.8 多文件操作
將多個文件內容合并后進行處理:
cat?file.log?file.txt?|?grep?'error'?|?sort?|?uniq