單引號和雙引號
單引號:可以說是所見即所得:即將單引號內的內容原樣輸出,或者描述為單引號里面看到的是什么就會輸出什么。單引號''是全引用,被單引號括起的內容不管是常量還是變量者不會發生替換。
雙引號:把雙引號內的內容輸出出來;如果內容中有命令、變量等,會先把變量、命令解析出結果,然后在輸出最終內容來。雙引號""是部分引用,被雙引號括起的內容常量還是常量,變量則會發生替換,替換成變量內容。
不加引號:不會將含有空格的字符串視為一個整體輸出, 如果內容中有命令、變量等,會先把變量、命令解析出結果,然后在輸出最終內容來,如果字符串中帶有空格等特殊字符,則不能完整的輸出,需要改加雙引號,一般連續的字符串,數字,路徑等可以用。
使用規則:一般常量用單引號''括起,如果含有變量則用雙引號""括起。
最大不同:單引號與雙引號的最大不同在於雙引號仍然可以保有變數的內容,但單引號內僅能是一般字元,而不會有特殊符號
使用舉例:
""號里面遇到$,\等特殊字符會進行相應的變量替換
''號里面的所有字符都保持原樣
對於字符串,兩者相同,匹配模式也大致相同,但有一些區別非常容易混淆
grep "$a" file #引用變量a,查找變量a的值
grep '$a' file #查找“$a”字符串
grep "\\" file #grep: Trailing backslash(不知原因)
grep '\\' file #查找‘\’字符
1、$ 美元符
2、\ 反斜杠
3、` 反引號
4、" 雙引號
這四個字符在雙引號中是具有特殊含義的,其他都沒有,而單引號使所有字符都失去特殊含義
如果用雙引號,查找一個\,就應該用四個\:
grep "\\\\" file 這樣就對了,這樣等同於:
grep '\\' file
第一條命令shell把四個\,轉義成2個\傳遞給grep,grep再把2個\轉義成一個\查找
第二條命令shell沒轉義,直接把2個\傳遞給grep,grep再把2個\轉義成一個\查找
其實grep執行的是相同的命令
還有一種情況是查找的內容含有單引號,也含有變量如$HOME,如文件:
"$HOME'
這時候 grep '"$HOME''的話,因為內容有單引號,第一個單引號會和倒數第二個單引號匹配,導致找不到正確內容,這里只能用雙引號(如有單引號方法可以留言討論),即grep "\"\$HOME'"。
結論:當grep的字符串中有單引號時,需要使用雙引號,以防止單引號匹配錯誤。但這也會導致不想轉換的變量被雙引號轉換,只能用\轉義。
常用選項
-E :開啟擴展(Extend)的正則表達式,相當於egrep -e:同時匹配多個目標 -i :忽略大小寫(ignore case) -v:反向查找(invert),只打印沒有匹配的,而匹配的反而不打印。 -n:顯示行號 -i:忽略大小寫 -c:顯示總共有多少行被匹配到了,而不是顯示被匹配到的內容,注意如果同時使用-cv選項是顯示有多少行沒有被匹配到。 -P:使用兼容perl的正則 -w:被匹配的文本只能是單詞,而不能是單詞中的某一部分,也就是精確匹配。如文本中有liker,而我搜尋的只是like,就可以使用-w選項來避免匹配liker fgrep: 不支持正則表達式,只能匹配寫死的字符串,但是速度奇快,效率高,fastgrep -o:只顯示被模式匹配到的字符串。 -q:靜默模式,只關心有沒有匹配到,不關心內容 --color :將匹配到的內容以顏色高亮顯示,centos7默認已經高亮。 -A n:顯示匹配到的字符串所在的行及其后n行,after -B n:顯示匹配到的字符串所在的行及其前n行,before -C n:顯示匹配到的字符串所在的行及其前后各n行,context
例子:
1、去除空行;去除注釋行;去除空行和注釋行
grep -v '^$' abc.txt grep -v '^#' abc.txt egrep -v '^$|^#' abc.txt 或 grep -Ev '^$|^#' abc.txt 或 grep -Ev "^$|^[#;]" abc.txt
grep的規則表達式
\ 反義字符:如"\"\""表示匹配"" [ - ] 匹配一個范圍,[0-9a-zA-Z]匹配所有數字和字母 * 所有字符,長度可為0 + 前面的字符出現了一次或者多次 ^ #匹配行的開始 如:'^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。
POSIX字符:
為了在不同國家的字符編碼中保持一至,POSIX(The Portable Operating System Interface)增加了特殊的字符類,如[:alnum:]是[A-Za-z0-9]的另一個寫法。要把它們放到[]號內才能成為正則表達式,如[A- Za-z0-9]或[[:alnum:]]。在linux下的grep除fgrep外,都支持POSIX的字符類。
[:alnum:] #文字數字字符 [:alpha:] #文字字符 [:digit:] #數字字符 [:graph:] #非空字符(非空格、控制字符) [:lower:] #小寫字符 [:cntrl:] #控制字符 [:print:] #非空字符(包括空格) [:punct:] #標點符號 [:space:] #所有空白字符(新行,空格,制表符) [:upper:] #大寫字符 [:xdigit:] #十六進制數字(0-9,a-f,A-F)
例子:
1、匹配文件中所有單詞,並打印出來
grep -E -o "\b[[:alpha:]]+\b" abc.txt # [[:alpha:]]表示字母 # [[:alpha:]]+表示多個字母 # \b表示邊界,其前后必須是不同類型的字符 # \b[[:alpha:]]+\b合起來表示一個單詞