![]() ![]() (This also happens with a ^ that is not at the beginning of an expression, and a $ that is not in a position to match end of line: They are interpreted as the normal characters ^ and $. Probably the last two lines above in double quotes explain why the results in your test ( \| vs \\|) have the same regex operation when enclosed in double quotes.In BRE (Basic regular expressions) that grep uses (as opposed to ERE, extended REs from egrep or grep -E, if a * is nor a quantifier of a preceding expression, it will match the literal star. Tt -e "def\\|aaa" #Displays def\|aaa (same as before - not correct parsing) Tt -e "def\|aaa" #Displays def\|aaa (correct parsing) Tt -e 'def\\|aaa' #Displays def\\|aaa (correct parsing) One step more: tt -e 'def\|aaa' #Displays def\|aaa (correct parsing) Mind the case of three and four slashes inside double quotes. Tt -e "def\\\\|aaa" #We send four slashes but function displays TWO Tt -e "def\\\|aaa" #We send three slashes but function displays TWO Tt -e "def\\|aaa" #We send two slashes but function displays ONE Tt -e 'def\\\\|aaa' #We send four slashes - function gets four slashes ![]() Tt -e 'def\\\|aaa' #We send three slashes - function gets three slashes See this bash function test results that prove different interpretation of single vs double quotes in args: function tt Should have something to do with bash expansion. $ cat -n file1 |grep -e 'def\\\\|zzz' #No resultsĬonclusion : For regex in grep use single quotes.īut to be honest, i don't know why the behavior is completelly different when using double quotes. $ cat -n file1 |grep -e 'def\\|zzz' #No results $ cat -n file1 |grep -e 'def|zzz' #No results Making some similar tests with single quotes we have a different and correct behavior: $ cat file1 As a consequence, the only difference between grep and grep -E for GNU grep is what has to be escaped functionality is identical.Īccording to grep man pages, and especially according to info pages, all examples given for grep include single quotes and not double quotes. In general, it's prudent to single quote your regular expression so the shell leaves it alone.Īs a side note, I don't think your C program is representative of how the shell processes arguments in Shell Operation, quoting is a separate step and includes backslash processing (see Escape Character).ġAs an extension, GNU grep allows you to escape | in BRE and get alternation. grep -e"def\\\|zzz" – the shell turns this into def\\|zzz ( \\ becomes \, \| isn't special to the shell and stays unchanged) grep sees \\ as a literal backslash ( backslash escaped by backslash), so | isn't special, and grep tries to match the exact string def\|zzz.grep -e"def\\|zzz" – \\ is special according to the manual excerpt (try echo "\\") grep sees def\|zzz because the shell removes a backslash, and the behaviour is the same as for the second case.grep -e"def\|zzz" – | isn't one of the special characters mentioned above, so grep receives def\|zzz, and GNU grep treats \| as alternation 1.grep -e"def|zzz" – grep receives def|zzz because it defaults to basic regular expressions (BRE), | isn't special 1 and grep tries to match the literal string def|zzz.This means that your expressions are treated as follows: Within double quotes, backslashes that are followed by one of these characters are removed. The backslash retains its special meaning only when followed by one of the following characters: $, `, ", \, or newline. ![]() If you double quote your regex, the shell treats backslashes specially (emphasis mine): I suspect grep itself does something special with the literal string \\|. So all double-quotes are removed and the backslashes and pipes are not altered by the shell. I investigated what my shell does with the command lines above : Using this simple argument-printing program, void main(int argc, char** argv) Escaping with three backslashes fails, echo abcdef | grep -e"def\\\|zzz"ĭoes anyone have an explanation, especially for the 2-backslash case ? More surprisingly, escaping with 2 backslashes also works, echo abcdef | grep -e"def\\|zzz" Escaping with one backslash works, echo abcdef | grep -e"def\|zzz" Outputs nothing, because grep is not in extended regex mode. I'm a little confused about how many backslashes are needed to escape the alternation operator | in regular expressions for grep. ![]()
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |