grep awk sed

來源:互聯網
上載者:User

1. grep簡介 grep (global search regular expression(RE) and print out the line,全面搜尋Regex並把行列印出來)是一種強大的文本搜尋工具,它能使用Regex搜尋文本,並把匹配的行列印出來。Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的擴充,支援更多的re元字元, fgrep就是fixed grep或fast grep,它們把所有的字母都看作單詞,也就是說,Regex中的元字元表示回其自身的字面意義,不再特殊。linux使用GNU版本的grep。它功能更強,可以通過-G、-E、-F命令列選項來使用egrep和fgrep的功能。 grep的工作方式是這樣的:它在一個或多個檔案中搜尋字串模板。如果模板包括空格,則必須被引用,模板後的所有字串被看作檔案名稱。搜尋的結果被送到螢幕,不影響原檔案內容。 grep可用於shell指令碼,因為grep通過返回一個狀態值來說明搜尋的狀態,如果模板搜尋成功,則返回0,如果搜尋不成功,則返回1,如果搜尋的檔案不存在,則返回2。我們利用這些傳回值就可進行一些自動化的文本處理工作。 1. grepRegex元字元集(基本集) ^ 錨定行的開始 如:'^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結尾的單詞的行。 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 單詞鎖定符,如: '/bgrepb/'只匹配grep。 2. 用於egrep和 grep -E的元字元擴充集 + 匹配一個或多個先前的字元。如:'[a-z]+able',匹配一個或多個小寫字母后跟able的串,如loveable,enable,disable等。 ? 匹配零個或多個先前的字元。如:'gr?p'匹配gr後跟一個或沒有字元,然後是p的行。 a|b|c 匹配a或b或c。如:grep|sed匹配grep或sed () 分組符號,如:love(able|rs)ov+匹配loveable或lovers,匹配一個或多個ov。 x{m},x{m,},x{m,n} 作用同x/{m/},x/{m,/},x/{m,n/} 4. POSIX字元類為了在不同國家的字元編碼中保持一至,POSIX(The Portable Operating System Interface)增加了特殊的字元類,如[:alnum:]是A-Za-z0-9的另一個寫法。要把它們放到[]號內才能成為Regex,如[A- Za-z0-9]或[[:alnum:]]。在linux下的grep除fgrep外,都支援POSIX的字元類。 [:alnum:] 文字數字字元 [:alpha:]文字字元 [:digit:] 數字字元 [:graph:] 非Null 字元(非空格、控制字元) [:lower:] 小寫字元 [:cntrl:] 控制字元 [:print:] 非Null 字元(包括空格) [:punct:] 標點符號 [:space:] 所有空白字元(新行,空格,定位字元) [:upper:] 大寫字元 [:xdigit:] 十六進位數字(0-9,a-f,A-F) 4. Grep命令選項 -? 同時顯示匹配行上下的?行,如:grep -2 pattern filename同時顯示匹配行的上下2行。 -b,--byte-offset 列印匹配行前面列印該行所在的塊號碼。 -c,--count 只列印匹配的行數,不顯示匹配的內容。 -f File,--file=File 從檔案中提模數板。空檔案中包含0個模板,所以什麼都不匹配。 -h,--no-filename 當搜尋多個檔案時,不顯示匹配檔案名稱首碼。 -i,--ignore-case 忽略大小寫差別。 -q,--quiet 取消顯示,只返回退出狀態。0則表示找到了匹配的行。 -l,--files-with-matches 列印匹配模板的檔案清單。 -L,--files-without-match 列印不匹配模板的檔案清單。 -n,--line-number 在匹配的行前面列印行號。 -s,--silent 不顯示關於不存在或者無法讀取檔案的錯誤資訊。 -v,--revert-match 反檢索,只顯示不匹配的行。 -w,--word-regexp 如果被/<和/>引用,就把運算式做為一個單詞搜尋。 -V,--version 顯示軟體版本資訊。 5. 執行個體要用好grep這個工具,其實就是要寫好Regex,所以這裡不對grep的所有功能進行執行個體講解,只列幾個例子,講解一個Regex的寫法。 $ ls -l | grep '^a' 通過管道過濾ls -l輸出的內容,只顯示以a開頭的行。 $ grep 'test' d* 顯示所有以d開頭的檔案中包含test的行。 $ grep 'test' aa bb cc 顯示在aa,bb,cc檔案中匹配test的行。 $ grep '[a-z]/{5/}' aa 顯示所有包含每個字串至少有5個連續小寫字元的字串的行。 $ grep 'w/(es/)t.*/1' aa 如果west被匹配,則es就被儲存到記憶體中,並標記為1,然後搜尋任意個字元(.*),這些字元後面緊跟著另外一個es(/1),找到就顯示該行。如果用egrep或grep -E,就不用"/"號進行轉義,直接寫成'w(es)t.*/1'就可以了。 awk 用法:awk ' pattern {action} ' 變數名 含義 ARGC 命令列變元個數 ARGV 命令列變元數組 FILENAME 當前輸入檔案名稱 FNR 當前檔案中的記錄號 FS 輸入欄位分隔字元,預設為一個空格 RS 輸入記錄分隔字元 NF 目前記錄裡域個數 NR 到目前為止記錄數 OFS 輸出域分隔字元 ORS 輸出記錄分隔字元 用法介紹: 1,模式比對 awk '/zqy/' fileA #尋找出fileA中含有zqy的行 等同於awk '$0~/zqy/' fileA awk '$1~/88/' fileA #找出第一個域裡麵包含88的行 awk '$1~/88/{print $2}' fileA #找出第一個域裡麵包含88的行後,只列印該行的第二個域 2,對不同的域進行操作 awk '$2 >25 && $2<=55' fileA #找出第二個域裡面滿足條件的行,可以加上{print $n}來列印任意域 ############### fileB ################# 884 46 1 8 5 944 734 41 0 10 2 787 647 29 1 8 1 686 536 26 1 9 0 572 ############### fileB ################# $ less fileB 884 46 1 8 5 944 734 41 0 10 2 787 647 29 1 8 1 686 536 26 1 9 0 572 $awk '{print NR,NF,$NF}' fileB # NR:檔案目前記錄號(在這裡可以理解為行數); NF:總的域的個數(可以理解為列數); $NF:想一想是什麼東西吧?再不知道就撞牆去吧。 1 6 944 2 6 787 3 6 686 4 6 572 3,通過-F參數來改變域分隔字元,FS設定輸入分隔字元,OFS設定輸出分隔字元,awk所有操作都支援管道。如: df | awk '$4>1000000 ' 通過管道符獲得輸入,如:顯示第4個域滿足條件的行。 awk -F "|" '{print $1}' file 按照新的分隔字元“|”進行操作。 awk 'BEGIN { FS="[: /t|]"}{print $1,$2,$3}' file 通過設定輸入分隔字元(FS="[: /t|]")修改輸入分隔字元。BEGIN 表示在處理任意行之前進行的操作。 awk 'BEGIN { OFS="%"} {print $1,$2,$3}' file 通過設定輸出分隔字元(OFS="%")修改輸出格式。 Sep="|" awk -F $Sep '{print $1}' file 按照環境變數Sep的值做為分隔字元。 awk -F '[ :/t|]' '{print $1}' file 按照Regex的值做為分隔字元,這裡代表空格、:、TAB、|同時做為分隔字元。 awk -F '[][]' '{print $1}' file 按照Regex的值做為分隔字元,這裡代表[、] 4、 awk -f awkfile file 通過檔案awkfile的內容依次進行控制。 cat awkfile /101/{print "/047 Hello! /047"} --遇到匹配行以後列印 ' Hello! './047代表單引號。 {print $1,$2} --因為沒有模式控制,列印每一行的前兩個域。 5、 awk 'BEGIN { max=100 ;print "max=" max} {max=($1 >max ?$1:max); print $1,"Now max is "max}' file 取得檔案第一個域的最大值。 awk '{print ($1>4 ? "high "$1: "low "$1)}' file 6、 awk '{$1 == 'Chi' {$3 = 'China'; print}' file 找到匹配行後先將第3個域替換後再顯示該行(記錄)。 awk '{$7 %= 3; print $7}' file 將第7域被3除,並將餘數賦給第7域再列印。 7、 awk '/tom/ {wage=$2+$3; printf wage}' file 找到匹配行後為變數wage賦值並列印該變數。 8、 awk '/tom/ {count++;} END {print "tom was found "count" times"}' file #END表示在所有輸入行處理完後進行處理。 9、awk 'gsub(//$/,"");gsub(/,/,""); cost+=$4;END {print "The total is $" cost>"filename"}' file gsub函數用空串替換$和,再將結果輸出到filename中。 1 2 3 $1,200.00 1 2 3 $2,300.00 1 2 3 $4,000.00 awk '{gsub(//$/,"");gsub(/,/,""); if ($4>1000&&$4<2000) c1+=$4; else if ($4>2000&&$4<3000) c2+=$4; else if ($4>3000&&$4<4000) c3+=$4; else c4+=$4; } END {printf "c1=[%d];c2=[%d];c3=[%d];c4=[%d]/n",c1,c2,c3,c4}"' file 通過if和else if完成條件陳述式 awk '{gsub(//$/,"");gsub(/,/,""); if ($4>3000&&$4<4000) exit; else c4+=$4; } END {printf "c1=[%d];c2=[%d];c3=[%d];c4=[%d]/n",c1,c2,c3,c4}"' file 通過exit在某條件時退出,但是仍執行END操作。 awk '{gsub(//$/,"");gsub(/,/,""); if ($4>3000) next; else c4+=$4; } END {printf "c4=[%d]/n",c4}"' file 通過next在某條件時跳過該行,對下一行執行操作。 10、awk '{ print FILENAME,$0 }' file1 file2 file3>fileall 把file1、file2、file3的檔案內容全部寫到fileall中,並前置檔案名稱。 11、awk ' $1!=previous { close(previous); previous=$1 } {print substr($0,index($0," ") +1)>$1}' fileall 把合并後的檔案重新分拆為3個檔案。並與原檔案一致。 12、awk 'BEGIN {"date"|getline d; print d}' 通過管道把date的執行結果送給getline,並賦給變數d,然後列印。 13、awk 'BEGIN {system("echo /"Input your name://c/""); getline d;print "/nYour name is",d,"/b!/n"}' 通過getline命令互動輸入name,並顯示出來。 awk 'BEGIN {FS=":"; while(getline< "/etc/passwd" >0) { if($1~"050[0-9]_") print $1}}' 列印/etc/passwd檔案中使用者名稱包含050x_的使用者名稱。 14、awk '{ i=1;while(i 錨定單詞的結束,如/love/>/匹配包含以love結尾的單詞的行。 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的行。 5. 執行個體 5.1刪除:d命令 * $ sed '2d' example-----刪除example檔案的第二行。 * $ sed '2,$d' example-----刪除example檔案的第二行到末尾所有行。 * $ sed '$d' example-----刪除example檔案的最後一行。 * $ sed '/test/'d example-----刪除example檔案所有包含test的行。 5.2替換:s命令 * $ sed 's/test/mytest/g' example-----在整行範圍內把test替換為mytest。如果沒有g標記,則只有每行第一個匹配的test被替換成mytest。 * $ sed -n 's/^test/mytest/p' example-----(-n)選項和p標誌一起使用表示只列印那些發生替換的行。也就是說,如果某一行開頭的test被替換成mytest,就列印它。 * $ sed 's/^192.168.0.1/&localhost/' example-----&符號表示替換換字串中被找到的部份。所有以192.168.0.1開頭的行都會被替換成它自已加 localhost,變成192.168.0.1localhost。 * $ sed -n 's//(love/)able//1rs/p' example-----love被標記為1,所有loveable會被替換成lovers,而且替換的行會被列印出來。 * $ sed 's#10#100#g' example-----不論什麼字元,緊跟著s命令的都被認為是新的分隔字元,所以,“#”在這裡是分隔字元,代替了預設的“/”分隔字元。表示把所有10替換成100。 5.3選定行的範圍:逗號 * $ sed -n '/test/,/check/p' example-----所有在模板test和check所確定的範圍內的行都被列印。 * $ sed -n '5,/^test/p' example-----列印從第五行開始到第一個包含以test開始的行之間的所有行。 * $ sed '/test/,/check/s/$/sed test/' example-----對於模板test和west之間的行,每行的末尾用字串sed test替換。 5.4多點編輯:e命令 * $ sed -e '1,5d' -e 's/test/check/' example-----(-e)選項允許在同一行裡執行多條命令。如例子所示,第一條命令刪除1至5行,第二條命令用check替換test。命令的執行順序對結果有影響。如果兩個命令都是替換命令,那麼第一個替換命令將影響第二個替換命令的結果。 * $ sed --expression='s/test/check/' --expression='/love/d' example-----一個比-e更好的命令是--expression。它能給sed運算式賦值。 5.5從檔案讀入:r命令 * $ sed '/test/r file' example-----file裡的內容被讀進來,顯示在與test匹配的行後面,如果匹配多行,則file的內容將顯示在所有匹配行的下面。 5.6寫入檔案:w命令 * $ sed -n '/test/w file' example-----在example中所有包含test的行都被寫入file裡。 5.7追加命令:a命令 * $ sed '/^test/a//--->this is a example' example<-----'this is a example'被追加到以test開頭的行後面,sed要求命令a後面有一個反斜線。 5.8插入:i命令 $ sed '/test/i// new line -------------------------' example 如果test被匹配,則把反斜線後面的文本插入到匹配行的前面。下一個:n命令 * $ sed '/test/{ n; s/aa/bb/; }' example-----如果test被匹配,則移動到匹配行的下一行,替換這一行的aa,變為bb,並列印該行,然後繼續。 5.9變形:y命令 * $ sed '1,10y/abcde/ABCDE/' example-----把1--10行內所有abcde轉變為大寫,注意,Regex元字元不能使用這個命令。 5.10退出:q命令 * $ sed '10q' example-----列印完第10行後,退出sed。 5.11保持和擷取:h命令和G命令 * $ sed -e '/test/h' -e '$G example-----在sed處理檔案的時候,每一行都被儲存在一個叫模式空間的臨時緩衝區中,除非行被刪除或者輸出被取消,否則所有被處理的行都將列印在螢幕上。接著模式空間被清空,並存入新的一行等待處理。在這個例子裡,匹配test的行被找到後,將存入模式空間,h命令將其複製並存入一個稱為保持緩衝區的特殊緩衝區內。第二條語句的意思是,當到達最後一行後,G命令取出保持緩衝區的行,然後把它放回模式空間中,且追加到現在已經存在於模式空間中的行的末尾。在這個例子中就是追加到最後一行。簡單來說,任何包含test的行都被複製並追加到該檔案的末尾。 5.12保持和互換:h命令和x命令 * $ sed -e '/test/h' -e '/check/x' example -----互換模式空間和保持緩衝區的內容。也就是把包含test與check的行互換。 6. 指令碼 Sed指令碼是一個sed的命令清單,啟動Sed時以-f選項引導指令檔名。Sed對於指令碼中輸入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多個命令,要用分號分隔。以#開頭的行為注釋行,且不能跨行。 7. 小技巧 * 在sed的命令列中引用shell變數時要使用雙引號,而不是通常所用的單引號。下面是一個根據name變數的內容來刪除named.conf檔案中zone段的指令碼: name='zone/ "localhost"' sed "/$name/,/};/d" named.conf

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.