Linux 文本處理三劍客:grep、sed 和 awk
發(fā)布時(shí)間:2024-01-18 16:46:32
awk、grep、sed是linux操作文本的三大利器,合稱文本三劍客,也是必須掌握的linux命令之一。三者的功能都是處理文本,但側(cè)重點(diǎn)各不相同,其中屬awk功能最強(qiáng)大,但也最復(fù)雜。grep更適合單純的查找或匹配文本,sed更適合編輯匹配到的文本,awk更適合格式化文本,對(duì)文本進(jìn)行較復(fù)雜格式處理。Linux 系統(tǒng)中 grep 命令是一種強(qiáng)大的文本搜索工具,它能使用正則表達(dá)式搜索文本,并把匹配的行打印出來(lái)。grep全稱是 Global Regular Expression Print,表示全局正則表達(dá)式版本,它的使用權(quán)限是所有用戶。grep可用于shell腳本,因?yàn)間rep通過(guò)返回一個(gè)狀態(tài)值來(lái)說(shuō)明搜索的狀態(tài),如果模板搜索成功,則返回0,如果搜索不成功,則返回1,如果搜索的文件不存在,則返回2。我們利用這些返回值就可進(jìn)行一些自動(dòng)化的文本處理工作。即便不熟悉這個(gè)命令,應(yīng)該大多數(shù)同學(xué)也用過(guò)查詢進(jìn)程的命令:這就是 grep 的一個(gè)基本用法,從所有進(jìn)程中搜索某個(gè)進(jìn)程。
- -A<行數(shù) x>:除了顯示符合范本樣式的那一列之外,并顯示該行之后的 x 行內(nèi)容。
- -B<行數(shù) x>:除了顯示符合樣式的那一行之外,并顯示該行之前的 x 行內(nèi)容。
- -C<行數(shù) x>:除了顯示符合樣式的那一行之外,并顯示該行之前后的 x 行內(nèi)容。
- -c:統(tǒng)計(jì)匹配的行數(shù)
- -e :實(shí)現(xiàn)多個(gè)選項(xiàng)間的邏輯or 關(guān)系
- -i --ignore-case #忽略字符大小寫的差別。
- -v:顯示不被 pattern 匹配到的行,相當(dāng)于[^] 反向匹配
前三個(gè) A、B、C 參數(shù)很容易理解,舉個(gè)栗子,假設(shè)我們有一個(gè)文件,文件名是 test,內(nèi)容是從 1 到 9,每個(gè)數(shù)字一行:-A2 7
的效果就是找到 7 ,然后輸出 7 后面兩行。同理,-B2 7
和-C2 7
就是找到 7 ,然后分別輸出 7 前面兩行和前后兩行:繼續(xù),假設(shè)我們有個(gè)名叫 test 的文件內(nèi)容如下:grep -c
命令的作用就是輸出匹配到的行數(shù),比如我們想找包含aaa
的有幾行,一眼就能看出來(lái)有兩行,第一行和第三行都包含:
grep -e
命令是實(shí)現(xiàn)多個(gè)匹配之間的或
關(guān)系,比如我們想找包含aaaa
或者bbbb
的,顯然應(yīng)該返回第一行和第二行:
grep -F
相當(dāng)于fgrep
命令,就是將pattern
視為固定字符串。比如搜索'aa*'
不帶-F
和帶上,區(qū)別如下:
可以看到第二次就找不到了,因?yàn)樗阉鞯氖?nbsp;aa*
這個(gè)字符串,而不是正則表達(dá)式。grep -f 文件名
的使用方法是把后面這個(gè)文件里的內(nèi)容當(dāng)做pattern
。比如我們有個(gè)文件,名字是 grep.txt,然后內(nèi)容是aa*
,使用方法如下:實(shí)際上等同于grep 'aa*' testgrep -i --ignore-case作用是忽略大小寫。grep -n顯示匹配的行號(hào),就是多顯示了個(gè)行號(hào),不用細(xì)說(shuō)。grep -o僅顯示匹配到的字符串,還是用剛才的aa*距離,之前顯示的都是匹配到的字符所在的整行,這個(gè)命令是只顯示匹配到的字符:grep -q不打印匹配結(jié)果。剛看到這個(gè)我疑惑了半天,讓你搜索字符串,你不給我結(jié)果那有啥用?然后發(fā)現(xiàn)還有一條很多教程沒(méi)說(shuō):如果有匹配的內(nèi)容則立即返回狀態(tài)值 0。所以一般用在shell腳本中,在 if 判斷里面。grep -v顯示不被匹配到的行,相當(dāng)于[^]反向匹配,最常見(jiàn)的還是用在查找線程的命令里,有時(shí)候會(huì)打印grep線程,可以再加上這么一個(gè)去除自己:? ps -ef|grep Typora
501 91616 1 0 五11上午 ?? 13:39.32 /Applications/Typora.app/Contents/MacOS/Typora
501 14814 93748 0 5:33下午 ttys002 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn Typora
? ps -ef|grep Typora|grep -v grep
501 91616 1 0 五11上午 ?? 13:39.32 /Applications/Typora.app/Contents/MacOS/Typora
可以看到第二次就沒(méi)有打印grep
線程自身grep -w
匹配整個(gè)單詞,只有完全符合pattern
的單次才會(huì)匹配到:可以看到第二次結(jié)果為空,因?yàn)闆](méi)有aaa
這個(gè)單詞。關(guān)于正則的高級(jí)用法就不再深入研究了,改日再統(tǒng)一整理。sed
sed
命令的作用是利用腳本來(lái)處理文本文件。使用方法:
- -e<script>或--expression=<script> 以選項(xiàng)中指定的 script 來(lái)處理輸入的文本文件,這個(gè)-e可以省略,直接寫表達(dá)式。
- -f<script文件>或--file=<script文件>以選項(xiàng)中指定的 script 文件來(lái)處理輸入的文本文件。
- -n 或 --quiet 或 --silent 僅顯示 script 處理后的結(jié)果。
- a:新增, a 的后面可以接字串,而這些字串會(huì)在新的一行出現(xiàn)(目前的下一行)~
- c:取代, c 的后面可以接字串,這些字串可以取代 n1,n2 之間的行!
- d:刪除,因?yàn)槭莿h除啊,所以 d 后面通常不接任何咚咚;
- i:插入, i 的后面可以接字串,而這些字串會(huì)在新的一行出現(xiàn)(目前的上一行);
- p:打印,亦即將某個(gè)選擇的數(shù)據(jù)印出。通常 p 會(huì)與參數(shù) sed -n 一起運(yùn)行~
- s:取代,通常這個(gè) s 的動(dòng)作可以搭配正規(guī)表示法,例如 1,20s/old/new/g 。
我們先準(zhǔn)備一個(gè)文件,名為test做測(cè)試,內(nèi)容如下:增加內(nèi)容
使用命令sed -e 3a\newLine testfile
這個(gè)命令的意思就是,在第三行后面追加newLine
這么一行字符,字符前面要用反斜線作區(qū)分。執(zhí)行完畢之后可以看到結(jié)果:但是注意,這個(gè)只是將文字處理了,沒(méi)有寫入到文件里,文件里還是之前的內(nèi)容。其實(shí) a 前面是可以匹配字符串,比如我們只想在出現(xiàn) Linux 的行后面追加,就可以:sed -e /Linux/a\newline test 兩個(gè)斜線之間的內(nèi)容是需要匹配的內(nèi)容??梢钥闯?,只有第二、第四行有Linux,所以結(jié)果如下:這里用雙引號(hào)把整個(gè)表達(dá)式括起來(lái)也可以,還方便處理帶空格的字符。sed -e /Linux/a\newline test等效于sed "/Linux/a newline" test跟 a 類似,sed 3i\newline test是在第三行前面插入newline:sed /Linux/i\newline test
是在所有匹配到Linux
的行前面插入: