Linux 命令之 grep -- 强大的文本搜索工具/正则表达式搜索
文章目錄
- 一、命令介紹
- 二、grep 的三種形式
- 三、常用選項
- 四、正則表達式
- 五、參考示例
- 在指定的文件中查找指定的關鍵詞
- 查看指定文件中含有特定關鍵詞的文本行
- 查看指定文件中所有包含數字的行
- 在指定的目錄下遞歸搜索指定的字符串,將符合的文本行及其文件名輸出
- 在指定文件中搜索指定的字符串,將包含該字符串的行以及后面的指定行數都顯示出來
- 將指定文件中含有指定字符串的行及其后面指定數量的行打印輸出,且打印每行的字節偏移量
- 在指定的多個文件中搜索指定字符串,并且輸出匹配的行及其所屬的文件名
- 在指定文件中查找指定字符串,且僅輸出匹配到的行數
- 在指定目錄及其子目錄的所有文件中查找指定字符串,并返回匹配到的文本行內容及對應的文件名
- 只在一級子目錄中的特定文件中查找指定的關鍵詞(不在當前目錄中的文件查找)
- 查看二級子目錄(子目錄的子目錄)中的特定文件中含有指定關鍵詞的文本行內容
- 查看當前目錄及其所有子目錄下的文件中含有指定關鍵詞的文本行內容及對應文件名
- 顯示指定文件中符合范本樣式的文本行內容及對應的行號
- 列出文件內容中含有指定關鍵詞的文件名
- 查看指定文件中含有完整匹配搜索詞的匹配項的文本行
- 列出指定目錄下的文件中匹配范本樣式的字符串及對應的文件名
- 查看指定目錄下的文件內容含有符合指定范本樣式的字符串的文件名稱
- 查看指定目錄下的文件內容含有匹配正則表達式字符串的文本行內容和文件名
- 查看指定的目錄下除了特定文件之外的文件內容中含有指定關鍵詞的文件名
- 限定在指定文件中進行搜索
- 在指定目錄下查找,并且將特定的目錄排除在搜索范圍之外
- 將指定目錄中的所有文件所包含的指定字符串替換成另外一個指定的字符串
- 六、grep 和 find 的區別
一、命令介紹
grep 是 Global Search Regular Expression And Print Out The Line 或 Global Regular Expression Print 的簡稱,意思是全面搜索正則表達式,并將其打印出來。這個命令可以結合正則表達式使用,它也是 Linux 使用最為廣泛的命令。
grep 命令的選項用于對搜索過程的補充,而其命令的模式十分靈活,可以是變量、字符串、正則表達式。需要注意的是,一旦模式中包含了空格,務必要用雙引號將其引起來。
grep 后面跟著的搜索詞可以加上單引號或者雙引號,也可以不加任何引號;grep 可以在多種格式的文件中查找指定的內容,例如:json、html、txt、docx 等。
二、grep 的三種形式
Linux 支持三種形式的 grep
- grep:標準 grep 命令
- egrep:簡稱擴展 grep 命令,其實和 grep -E 等價,支持基本和擴展的正則表達式
- fgrep:簡稱快速 grep 命令,其實和 grep -F 等價,不支持正則表達式,按照字符串表面意思進行匹配
三、常用選項
| -a 或 --text | 不要忽略二進制數據 |
| -A <n> 或 --after-context=<n> | 后面需要跟著具體的文件名,選項后跟著數值,表示除了顯示包含符合范本樣式字符串的文本行以外,并顯示該行之后的 n 行內容 |
| -B<n> 或 --before-context=<n> | 后面需要跟著具體的文件名,選項后跟著數值,表示除了顯示包含符合范本樣式字符串的文本行以外,并顯示該行之前的 n 行內容 |
| -b<n> 或 --byte-offset | 后面需要跟著具體的文件名,不僅輸出包含指定符合范本樣式字符串的行,而且在每行輸出之前打印每行基于上一行開始處的字節偏移量 |
| -c 或 --count | 后面需要跟著具體的文件名,輸出符合范本樣式的行數 |
| -C<n> 或 --context=<n> 或 -<n> | 該選項后面必須指定數值,選項 -C 和后面的數值可以有無空格;選項 --context 與后面的數值必須有空格,也可以使用等號 =,但是等號與選項和數值之間不允許有空格;選項 - 與后面的數值之間不允許有空格。除了顯示符合范本樣式的那一行之外,并顯示該行之后 n 行的內容 |
| -d <ACTION> 或 --directories=<ACTION> | 如果輸入文件是一個目錄,請使用 ACTION 對其進行處理。默認情況下,ACTION 是 read,即讀取目錄,就像它們是普通文件一樣。如果操作是 skip,則自動跳過目錄。如果操作是 recurse[ri’k?s],則以遞歸方式讀取每個目錄下的所有文件,僅當符號鏈接位于命令行上時,才跟隨符號鏈接。這相當于 -r 選項 |
| -D <ACTION> 或 --devices=<ACTION> | 如果輸入文件是設備、FIFO 或 socket,請使用 ACTION 對其進行處理。默認情況下,ACTION 是 read,這意味著讀取設備就像讀取普通文件一樣。如果操作是 skip,則設備將被自動跳過 |
| -e<PATTERN> 或 --regexp=<PATTERN> | 指定搜索輸入時使用的模式:如果輸入行與指定的任何模式匹配,則選中該行。當使用多個 -e 選項指定多個模式時,或者當模式以破折號 - 開頭時,此選項最有用 |
| -E 或 --extended-regexp | 將模式解釋為擴展的正則表達式(即強制grep表現為egrep) |
| -f<范本文件> 或 --file=<規則文件> | 指定范本文件,其內容有一個或多個范本樣式,讓 grep 查找符合范本條件的文件內容,格式為每一行的范本樣式 |
| -F 或 --fixed-regexp | 將模式解釋為一組固定字符串(即強制grep作為fgrep) |
| -G 或 --basic-regexp | 將模式解釋為一個基本的正則表達式(即強制grep像傳統的grep那樣工作) |
| -h或--no-filename | 顯示含有符合范本樣式的字符串的文本行內容,但是不顯示該行所屬的文件名稱,在多文件中查詢默認會顯示對應的文件名 |
| -H 或 --with-filename | 當在指定的多個文件中查找指定的字符串時,不僅將包含指定字符串的行打印輸出,同時也輸出該行所屬的文件名 |
| -i 或 --ignore-case | 忽略大小寫差異,使大小寫不同的字符相互匹配 |
| -l或 --file-with-matches | 列出文件內容含有符合指定范本樣式的字符串的文件名稱 |
| -L 或--files-without-match | 列出文件內容不含有符合指定范本樣式的字符串的文件名稱 |
| -n或 --line-number | 顯示符合范本樣式的文本行內容的同時也在每行前面標示出對應的行號 |
| -q 或 --quiet 或 --silent | 不顯示任何信息 |
| -r 或 -R 或 --recursive | 此參數的效果和指定 -d recurse 參數相同 |
| -s 或 --no-messages | 不顯示錯誤信息 |
| -v 或--revert-match | 從指定文件的內容中查找不匹配指定字符串的行 |
| -V 或 --version | 顯示版本信息 |
| -w 或 --word-regexp | 只選擇那些包含構成整個單詞的匹配項的行。所謂構成整個單詞是指所匹配的子字符串前面必須跟著非單詞字符,后面也必須跟著非單詞字符。所謂單詞字符是指:字母、數字和下劃線,其它字符都是非單詞字符。如還指定了選項 -x,則此選項無效 |
| -x 或 --line-regexp | 只顯示整行都匹配指定的范本樣式的行 |
| -y | 此參數效果跟 -i 相同 |
| -o | 只輸出文件中匹配到的部分,把文件內容中所有符合范本樣式的字符串打印輸出 |
| -m <num> 或 --max-count=<num> | 找到 num 行結果后停止查找,用來限制匹配行數 |
四、正則表達式
| ^ | 錨(máo)定行的開始 如:’^grep’匹配所有以grep開頭的行 |
| $ | 錨定行的結束 如:‘grep$’ 匹配所有以grep結尾的行 |
| . | 匹配一個非換行符的字符 如:'gr.p’匹配gr后接一個任意字符,然后是p |
| * | 匹配零個或多個先前字符如:’*grep’匹配所有一個或多個空格后緊跟grep的行 |
| .* | 一起用代表任意字符 |
| [] | 匹配一個指定范圍內的字符,如’[Gg]rep’匹配Grep和grep |
| [^] | 匹配一個不在指定范圍內的字符,如:’[^A-FH-Z]rep’匹配不包含A-R和T-Z的一個字母開頭,緊跟rep的行 |
| \(..\) | 標記匹配字符,如’(love)’,love被標記為1 |
| \< | 錨定單詞的開始,如:’<grep’匹配包含以grep開頭的單詞的行 |
| \> | 錨定單詞的結束,如’grep>'匹配包含以grep結尾的單詞的行 |
| x\{m\} | 重復字符x,m次,如:'0{5}'匹配包含5個o的行 |
| x\{m,\} | 重復字符x,至少m次,如:'o{5,}'匹配至少有5個o的行 |
| x\{m,n\} | 重復字符x,至少m次,不多于n次,如:'o{5,10}'匹配5–10個o的行 |
| \w | 匹配文字和數字字符,也就是[A-Za-z0-9],如:'G\w*p’匹配以G后跟零個或多個文字或數字字符,然后是p |
| \W | \w的反置形式,匹配一個或多個非單詞字符,如點號句號等 |
| \b | 單詞鎖定符,如: '\bgrep\b’只匹配grep |
五、參考示例
在指定的文件中查找指定的關鍵詞
在文件 /root/test/text.txt 中查找關鍵詞“world”,會輸出匹配到的文本行內容:
[root@htlwk0001host ~]# grep world /root/test/text.txt hello shell world! shell world查看指定文件中含有特定關鍵詞的文本行
查看文件 text4.txt 中以 Aug 開始的文本行:
[root@htlwk0001host test1]# grep ^Aug text4.txt Augfsdf Augfsdfds注:^ 這是正則表達式的元字符,表示匹配行首。^Aug 表示匹配行首的字符串 Aug
查看指定文件中所有包含數字的行
grep [0-9] /var/log/messages # 選擇 '/var/log/messages' 文件中所有包含數字的行在指定的目錄下遞歸搜索指定的字符串,將符合的文本行及其文件名輸出
查看目錄 /var/log 及其所有的子目錄中包含字符串"Aug" 的文本行和對應的文件名:
grep Aug -R /var/log/*在指定文件中搜索指定的字符串,將包含該字符串的行以及后面的指定行數都顯示出來
例如,在文件 /root/test/text.txt 中查找字符串“world”,如果存在則將所在行以及后面的3行打印輸出:
[root@htlwk0001host ~]# grep -A 3 'world' /root/test/text.txt hello shell world! # 該行含有字符串 world,輸出此行及其后面的 3 行,但是后面只有 2 行,則輸出 2 行 dfdskklllllf dfsfdsf shell world # 該行含有字符串 world,輸出此行及其后面的 3 行 sdffdsfdsfd dfsfdfdsfds fsdfdsfdsfdsf我們看下文件 /root/test/text.txt 中的實際內容是什么:
[root@htlwk0001host test]# cat text.txt hello shell world! dfdskklllllf dfsfdsf shell world sdffdsfdsfd dfsfdfdsfds fsdfdsfdsfdsf fdsfdsfdsfd選項 -A 和數值之間允許有空格,也允許沒有空格:
[root@htlwk0001host ~]# grep -A3 'world' /root/test/text.txt還可以使用選項 --after-context 查詢,不過該選項和數值之間必須有空格,否則會報錯:
[root@htlwk0001host ~]# grep --after-context 3 'world' /root/test/text.txt另外選項 --after-context 還可以使用等號 = 來指定數值,但是等號 = 左右兩端不可以有空格:
[root@htlwk0001host ~]# grep --after-context=3 'world' /root/test/text.txt將指定文件中含有指定字符串的行及其后面指定數量的行打印輸出,且打印每行的字節偏移量
將文件 /root/test/text.txt 中含有字符串“world”的行及其后面的 3 行打印輸出,且打印每行的字節偏移量:
[root@htlwk0001host ~]# grep -b3 'world' /root/test/text.txt # 選項 -b 和數值之間不可以有空格 0:hello shell world! 19-dfdskklllllf # 該行的第 1 個字符 d 正好是前面一行從 h 開始數起的第 19 個字符 32-dfsfdsf # 該行的第 1 個字符 d 也正好是前面一行從 d 開始數起的第 13 位,那么加上前面一行 d 的偏移量 19,就是 32 40:shell world # 該行的第 1 個字符 s 是前面一行從 d 開始數起的第 8 位,那么加上前面一行 d 的偏移量 32,就是 40 52-sdffdsfdsfd 64-dfsfdfdsfds 76-fsdfdsfdsfdsf選項 -b 后面不跟著數值,則只打印包含指定字符串的行及其字節偏移量:
[root@htlwk0001host ~]# grep -b 'world' /root/test/text.txt 0:hello shell world! 40:shell world還可以使用選項 --byte-offset,但是該選項后面不可以跟著數值:
[root@htlwk0001host ~]# grep --byte-offset 'world' /root/test/text.txt 0:hello shell world! 40:shell world還可以指定多個文件進行查找:
[root@htlwk0001host test]# grep -b3 'world' text.txt text1.txt text.txt:0:hello shell world! text.txt-19-dfdskklllllf text.txt-32-dfsfdsf text.txt:40:shell world text.txt-52-sdffdsfdsfd text.txt-64-dfsfdfdsfds text.txt-76-fsdfdsfdsfdsf -- text1.txt:0:dsfdsaljflvoworlddslfljds324432 text1.txt-32-sfdsgdflfmbndfkjgrut3409t8ierrig text1.txt:65:gkldfjgleoeworldsdlfjdlsworld text1.txt-95-dsfdsfdsf text1.txt-105-fdsfdsfdsfdsfdsfsdfsdfsdf text1.txt-131-dsfsdfdsfsddfgdfgdfgdfgewreeortreoitureoimbn在指定的多個文件中搜索指定字符串,并且輸出匹配的行及其所屬的文件名
[root@htlwk0001host ~]# grep -H 'world' /root/test/text.txt /root/test/text2.txt /root/test/text.txt:hello shell world! /root/test/text.txt:shell world以上結果顯示,匹配到兩行文本,且這兩行內容都是在文件 /root/test/text.txt 中。
在指定文件中查找指定字符串,且僅輸出匹配到的行數
[root@htlwk0001host test]# grep -c 'world' text.txt text1.txt text.txt:2 # 文件 text.txt 匹配到 2 行 text1.txt:2 # 文件 text1.txt 也匹配到 2 行在指定目錄及其子目錄的所有文件中查找指定字符串,并返回匹配到的文本行內容及對應的文件名
[root@htlwk0001host test]# grep 'world' -d recurse ./ ./text.txt:hello shell world! ./text.txt:shell world ./tf_company_20210603.sql:Bigworld引擎的游戲開發技術。整個團隊的核心成員均來自國內頂尖游戲研發公司,并全部擁有兩個以上完整大型MMORPG項目的開發及運營經驗。作為擁有國內創業公司中最強開發實力的第四代互聯網企業,境界公司旨在為用戶創造精致有趣,豐富平衡的3D游戲世界。 公司網址 www.363.com', 0.00, 0, 0, 0, 0.0000, '2021-02-17 14:34:47', '2021-02-17 14:34:47', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); ./tf_company_20210603.sql:3, 4, 1, NULL, '無憂互通(www.sail2world.com),是一家專注于提供最領先的移動游戲和互聯網娛樂產品的研發商和運營商。 ./tf_company_20210603.sql:the world, with 45'2021-02-26 14:47:21', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); ./text1.txt:dsfdsaljflvoworlddslfljds324432 ./text1.txt:gkldfjgleoeworldsdlfjdlsworld[root@htlwk0001host ~]# grep 'make' -d recurse ./test ./test/text.html:<p class="p1">ffdsfsmakefdsfsdfmake</p> ./test/text.html:<p class="p1">sdfsdfdsmake</p> ./test/text.docx:fsdfdsmakesdfsdfsdfds ./test/text.docx:makedsfsdfdsfd ./test/text.txt:Sdfsd make love3434sdfdsfs ./test/text.txt:Fdsfgmake dsfsdf;dgdfdf ./test/text.txt:Make ldsfdsfmake lovefsdf343dv.,.,,.fdsfdsf ./test/text.json:make lovesdlfjf23423432dsffdsf ./test/text.json:sdfldjlfksjff makefsfddsfdsdsf24234ewdfd ./test/text.json:sfdmakesdfdsfds注:選項 -d 后面必須跟著操作項(read/skip/recurse)和目錄,但是其它兩種 ACTION 在實際業務中比較少使用,另外操作項 read 非常奇怪,你指定了 read,后面反而不能跟著目錄,必須跟著文件
只在一級子目錄中的特定文件中查找指定的關鍵詞(不在當前目錄中的文件查找)
[root@htlwk0001host ~]# grep 'make' */*.docx make23434354注:第一個 * 表示一級子目錄,第二個 * 表示匹配以 docx 為擴展名的任意文件名
查看二級子目錄(子目錄的子目錄)中的特定文件中含有指定關鍵詞的文本行內容
[root@htlwk0001host ~]# grep 'make' */*/*.docx fsdfdsmakesdfsdfsdfds makedsfsdfdsfd注:只在二級子目錄下的文件中查找,不會在當前目錄、一級子目錄及二級子目錄下的所有子目錄中查找
查看當前目錄及其所有子目錄下的文件中含有指定關鍵詞的文本行內容及對應文件名
在當前目錄及其所有子目錄中的文件查找字符串“make”,命令如下:
lwxdeMacBook-Air:test lwx$ grep make -r . ./text.html:<p class="p1">ffdsfsmakefdsfsdfmake</p> ./text.html:<p class="p1">sdfsdfdsmake</p> ./test1/text1.txt:make lovesdfsdfd23423 ./text.docx:fsdfdsmakesdfsdfsdfds ./text.docx:makedsfsdfdsfd ./text.txt:Sdfsd make love3434sdfdsfs ./text.txt:Fdsfgmake dsfsdf;dgdfdf ./text.txt:Make ldsfdsfmake lovefsdf343dv.,.,,.fdsfdsf ./text.json:make lovesdlfjf23423432dsffdsf ./text.json:sdfldjlfksjff makefsfddsfdsdsf24234ewdfd ./text.json:sfdmakesdfdsfds注:選項 -r 表示遞歸,搜索關鍵詞可以不加引號。
顯示指定文件中符合范本樣式的文本行內容及對應的行號
[root@htlwk0001host ~]# grep -n 'world' /root/test/text.txt 1:hello shell world! 4:shell world列出文件內容中含有指定關鍵詞的文件名
將當前目錄及其所有子目錄中的文件內容中含有字符串“make”的文件名打印輸出:
liaowenxiongdeMacBook-Air:test liaowenxiong$ grep make -r . | cut -d: -f1 | uniq ./text.html ./test1/text1.txt ./text.docx ./text.txt ./text.json注:cut 是字符串分割命令,-d 用來定義分割符號,-d: 表示將冒號 : 定義為分隔符,-f 顯示指定字段的內容,-f1 表示顯示第 1 個字段的內容。所以像這樣的字符串“./text.docx:makedsfsdfdsfd”,會被分割成“./text.docx”和“makedsfsdfdsfd”,顯示第 1 個字段的內容就是“./text.docx”,因為同個文件中有多行匹配到指定的關鍵詞,所以分割和取第 1 個字段的內容后會存在重復的數據,那么把命令 cut 處理后的數據再輸出給命令 uniq 進行去重后就得到上述的結果了。
查看指定文件中含有完整匹配搜索詞的匹配項的文本行
如下圖所示:
注:所謂完整匹配范本樣式,是指匹配項不僅僅內容匹配,而且匹配項的前后必須跟著非單詞字符才行。例如,上圖中的字符串“worldworl”的確含有搜索詞“world”,但是后面跟著單詞字符 w,所以不滿足要求。
列出指定目錄下的文件中匹配范本樣式的字符串及對應的文件名
在把文件內容中所有符合范本樣式的字符串打印輸出
在當前目錄及其所有的子目錄下的文件中查找關鍵詞“world”,并將匹配到的字符串打印輸出:
查看指定目錄下的文件內容含有符合指定范本樣式的字符串的文件名稱
查看當前目錄及其子目錄中的內容含有指定關鍵詞“world”的文件名:
[root@htlwk0001host test]# grep world -l -r . ./text.txt ./tf_company_20210603.sql ./test1/text4.txt ./text1.txt注:-l 表示查看內容匹配 pattern 的文件名;-r 表示對指定的目錄遞歸處理。
查看指定目錄下的文件內容含有匹配正則表達式字符串的文本行內容和文件名
[root@htlwk0001host test]# grep '[^a-z]oo' -n -r . ./text.txt:5:worldeeworld.'oo ./text.txt:6:sdf33oofdsfdsfd ./text.txt:8:dfsfdfdsfds=oo注:-n 表示輸出對應的行號,正則表達式可以加單引號或者雙引號,也可以不加引號。
查看指定的目錄下除了特定文件之外的文件內容中含有指定關鍵詞的文件名
列出目錄 /etc 及其所有子目錄下的文件內容含有關鍵詞“bash”的文件名,但是以 .conf 為后綴名的文件不在搜索范圍之內:
grep -Ril --exclude=*.conf bash /etc/*注:--exclude 用來指定被排除的文件
限定在指定文件中進行搜索
只在目錄 /etc 及其子目錄下的配置文件(擴展名為 .conf)中搜索指定的字符串“bash”,并將匹配到的文件名輸出:
grep -Ril --include=*.conf bash /etc/*在指定目錄下查找,并且將特定的目錄排除在搜索范圍之外
查看 /etc 及其子目錄中的內容包含完整匹配字符串 stretch 的匹配項的文件名,但不包括 /etc/grub.d 目錄下的文件:
# grep --exclude-dir=/etc/grub.d -Rwl stretch /etc/* /etc/apt/sources.list /etc/dictionaries-common/words /etc/os-release將指定目錄中的所有文件所包含的指定字符串替換成另外一個指定的字符串
將當前目錄及其所有子目錄中的所有文件內容中的關鍵詞“aliyun” 替換成“lwx”:
[cqs@centos7]$ sed -i "s/aliyun/lwx/g" `grep -rl aliyun ./`注:后面的 grep 命令語句必須放在反撇號之內,這樣才會執行該命令語句
六、grep 和 find 的區別
grep 是查找文本內容,所以指定文件時則會進入文件內容中查找,而 find 是查找文件名,無法查找文件的內容
總結
以上是生活随笔為你收集整理的Linux 命令之 grep -- 强大的文本搜索工具/正则表达式搜索的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 肯德基可以用骑士卡吗?
- 下一篇: Linux 命令之 sed -- 功能强