awk、grep、sed是linux操作文本的三大利器,合稱文本三劍客,也是必須掌握的linux命令之一。
正則表達式
POSIX正則表達式分為基本正則表達式(BRE)和擴展表達式(ERE)。
- 支持的命令
| 類型 | grep | sed | vi | more | egrep | awk |
|---|---|---|---|---|---|---|
| BRE | √ | √ | √ | √ | ||
| ERE | √ | √ |
- BRE 和ERE區(qū)別
| 字符 | 意義 | 支持的類型 |
|---|---|---|
| \ | 將下一個字符標記為特殊字符,或者將一個元字符轉(zhuǎn)義為普通字符。如n加上\匹配一個換行符。\則匹配一個\字符。 | BOTH |
| ^ | 匹配輸入字符串的開始位置 | BOTH |
| $ | 匹配輸入字符串的結(jié)束位置 | BOTH |
| * | 匹配前面的子表達式0次或者多次,如zo*能匹配z和zoo | BOTH |
| ? | 匹配前面的子表達式0次或者1次 | ERE |
| . | 匹配除\n之外的任何單個字符 | BOTH |
| + | 匹配前面的子表達式1次或者多次,如zo+能匹配zo和zoo,但不能匹配z | ERE |
| | | 匹配于|符號前或后的正則表達式 | ERE |
| {n,m} | 最少匹配n次,最多匹配m次和BRE的區(qū)別是不需要加\ | ERE |
| \{n\} | 匹配前面的子表達式n次 | BRE |
| \{n,\} | 至少匹配前面的子表達式n次 | BRE |
| \{n,m\} | 最少匹配n次,最多匹配m次 | BRE |
| \(\) | 將(與)間的模式存儲在特殊的保留空間 | BRE |
| \digit | 重復(fù)在(與)方括號內(nèi)第n個子模式至此點的模式 | BRE |
| [xyz] | 匹配xyz中的任何一個字符 | BOTH |
| [^xyz] | 匹配未包含的任意字符 | BOTH |
| [x-z] | 匹配小寫的字符 | BOTH |
GREP
grep 命令是一種強大的文本搜索工具,它能使用正則表達式搜索文本,并把匹配的行打印出來。grep全稱是 Global Regular Expression Print,表示全局正則表達式版本,它的使用權(quán)限是所有用戶。
命令的基本格式:grep [option] pattern file
option如下:
- -A<行數(shù) x>:除了顯示符合范本樣式的那一列之外,并顯示該行之后的 x 行內(nèi)容。
grep -A2 "george" pets.txt - -B<行數(shù) x>:除了顯示符合樣式的那一行之外,并顯示該行之前的 x 行內(nèi)容。
grep -B2 "george" pets.txt - -C<行數(shù) x>:除了顯示符合樣式的那一行之外,并顯示該行之前后的 x 行內(nèi)容。
grep -C2 "george" pets.txt - -c:統(tǒng)計匹配的行數(shù)
grep -c "name" pets.txt - -e :實現(xiàn)多個選項間的邏輯or 關(guān)系
grep -e "betty" -e "frank" pets.txt
grep -c -e "betty" -e "frank" pets.txt - -E:擴展的正則表達式
grep -E "[a-z]{4,}'s" pets.txt
grep "[a-z]\{4,\}'s" pets.txt - -f 文件名:從文件獲取 PATTERN 匹配
echo frank > patten.txt
grep -nf patten.txt pets.txt - -F :相當于fgrep
grep -F相當于fgrep命令,就是將pattern視為固定字符串。比如搜索'aa*'不帶-F和帶上,區(qū)別如下:
echo aaaa | grep "aa*"
echo aaaa | grep -F "aa*"
echo aa* | grep -F "aa*" - -i --ignore-case #忽略字符大小寫的差別。
grep -i "Frank" pets.txt - -n:顯示匹配的行號
grep -in "dog" pets.txt - -o:僅顯示匹配到的字符串
grep -o "dog" pets.txt - -q: 靜默模式,不輸出任何信息
多用于shell腳本中,做if判斷 - -s:不顯示錯誤信息。
- -v:顯示不被 pattern 匹配到的行,相當于[^] 反向匹配
grep -v "dog" pets.txt - -w :匹配 整個單詞
grep "do" pets
grep -w "do" pets.txt
AWK
awk是一個強大的文本分析工具,相對于grep的查找,sed的編輯,awk在其對數(shù)據(jù)分析并生成報告時,顯得尤為強大。簡單來說awk就是把文件逐行的讀入,以空格為默認分隔符將每行切片,切開的部分再進行各種分析處理。對于日志、CSV 那樣的每行格式相同的文本文件,awk可能是最方便的工具。
之所以叫 AWK 是因為其取了三位創(chuàng)始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。
命令的基本格式: *awk '{[pattern] action}' {filenames} *
變量
- $num表示第num列
- NF表示有多少列
- NR表示第幾行
awk '{print NR,$NF}' pets.txt
分隔符
- FS:字段分隔符,默認是空格和制表符。
- RS:行分隔符,用于分割每一行,默認是換行符。
- OFS:輸出字段的分隔符,用于打印時分隔字段,默認為空格。
- ORS:輸出記錄的分隔符,用于打印時分隔記錄,默認為換行符。
- OFMT:數(shù)字輸出的格式,默認為%.6g。
echo a-b-c| awk -v OFS="/" -F "-" '{print NR,$NF}'
echo a,b,c,d#e,f,g,h | awk -v RS="#" -v OFS="/" -v ORS="," -F "," '{print $1,$2}' Desktop/test.txt
參數(shù)
- -v 變量替換
- -F 指定字段分隔符
模式
- NR 判斷
awk 'NR%2 ==0 {print $5}' pets.txt - 正則判斷
awk '/This/{print $4}' pets.txt - if 判斷
echo -e "12345ms\n4ms" | egrep -o "[0-9]+" | awk '{if(int($1) > 222) print $1; else print "----"}' - 函數(shù)
tolower():字符轉(zhuǎn)為小寫。
length():返回字符串長度。
substr():返回子字符串。
sin():正弦。
cos():余弦。
sqrt():平方根。
rand():隨機數(shù)。
https://www.gnu.org/software/gawk/manual/html_node/Built_002din.html#Built_002din
SED
sed 命令的作用是利用腳本來處理文本文件。sed全名叫stream editor,流編輯器,用程序的方式來編輯文本。
命令的基本格式: sed [-hnV][-e<script>][-f<script文件>][文本文件]
參數(shù)說明:
- -e<script>或--expression=<script> 以選項中指定的 script 來處理輸入的文本文件,這個-e可以省略,直接寫表達式。多個多項編輯。
- -f<script文件>或--file=<script文件>以選項中指定的 script 文件來處理輸入的文本文件。
- -n 取消默認輸出
- -i 覆蓋原文件
- -r使用擴展正則表達式
動作說明:
- a:新增, a 的后面可以接字串,而這些字串會在新的一行出現(xiàn)(目前的下一行)~
奇數(shù)行后增加
echo -e "1\n2\n3\n4\n5" | sed "1~2 a www" - c:取代, c 的后面可以接字串,這些字串可以取代 n1,n2 之間的行!
echo -e "1\n2\n3\n4\n5" | sed "1,2c www"
echo -e "1\n2\n3\n4\n5" | sed -e "1c www" -e "2c bb" - d:刪除,因為是刪除,所以 d 后面通常不接任何東西;
刪除注釋的行
echo -e "#todo\ndef s\nputs 'b'\nend" | sed "/^#/d" - i:插入, i 的后面可以接字串,而這些字串會在新的一行出現(xiàn)(目前的上一行);
echo -e "1\n2\n3\n4\n5" | sed "1 i aaa" - p:打印,亦即將某個選擇的數(shù)據(jù)印出。通常 p 會與參數(shù) sed -n 一起運行~
echo -e "1\n2\n3\n4\n5" | sed -n "1p" - s:取代,通常這個 s 的動作可以搭配正規(guī)表示法,例如 1,20s/old/new/g 。
替換每行第一個is 為was:sed 's/is/was/1' pets.txt
替換每行全部is為wassed 's/is/was/g' pets.txt
替換偶數(shù)行 is為wassed '1~2! s/is/was/g' pets.txt
覆蓋原文件sed -i '1~2! s/is/was/g' pets.txt