My source of question is the answer here on this link, plus some extra thingsUPDATEI understand the first command i.e grep \\[[a-z\|1-9]*\\] file but I don't understand the output of second command i.e grep \[[a-z\|1-9]*\] file.Now, I just want to understand how the output of second command is constructed especially why grep selected the whole third and fourth line completely, but selected the second and third line only up to the first ]
Understanding Escaping
shell;regular expression;escape characters
Lets walk slowly.If there is a file with this content (in just one line to make it easier to show):$ cat infilelist[1]; i[ab1]; var[1] [1]var  [1]var[2]aA simple grep --color a will show in red all the a's.(As this site does allow the control of colors : Assume that bold is red):$ grep --color a infile  list[1]; i[ab1]; var[1] [1]var  [1]var[2]Exactly the same happens if the a is un-quoted (as above) or if it is quoted:$ grep --color \a infile  list[1]; i[ab1]; var[1] [1]var  [1]var[2]$ grep --color a infile  list[1]; i[ab1]; var[1] [1]var  [1]var[2]$ grep --color 'a' infile  list[1]; i[ab1]; var[1] [1]var  [1]var[2]Why? Because the a's are both:Not special to the shell.The shell remove the quotes and grep receive the same a as first argument. Either a backslash quote, a double quote, or a single quote.]If we want to select the braces ] (lets start with the closing brace):$ grep --color ] infile  list[1]; i[ab1]; var[1][1]var  [1]var[2]The same will happen if the ] were quoted (any quote).In this case the ] is special to the shell but not in this case where there is no matching opening brace.For a closing brace, things get one step more complex. All of this raise an error:grep --color  [  infilegrep --color '[' infilegrep --color [ infileWhy? Because what grep receive in all cases is a single [.You can undestand what the shell does with this simple echo: $ echo \[ [ '[' [ [ [The shell remove one level of quoting and all values look the same.  [But what grep wants to receive to undestand that we are actually searching for the character [ is a backslash quoted square brace (\[). That will happen with all of this:$ echo \\[ \[ '\['\[ \[ \[And grep will work with any of those:$ grep --color \\[ infilelist[1]; i[ab1]; var[1][1]var[1]var[2][[]Using [[] (a character list with only one character) will get to the same result (as long as it is quoted).$ grep --color '[[]' infilelist[1]; i[ab1]; var[1][1]var[1]var[2]Grep needs to receive exactly [[] for this to work. It may seem that no quotes are really needed:$ echo \[\[\] [[] '[[]' [[][[] [[] [[] [[]But if you create a file named [, that idea will break:$ touch \[$ echo \[\[\] [[] '[[]' [[][[] [[] [[] [that is because the [ is special to the shell. To the shell, it starts a filename globbing pattern. If a file (or many) match the pattern, the list of files is substituted.So, this will work correctly:$  grep --color '[[]' infilelist[1]; i[ab1]; var[1][1]var[1]var[2]And this: grep --color '[]]' infile will match the closing brace.[][]To match both the opening square brace and the closing square brace, you need an specific sequence of characters (quoted, of course).If you try this:$  grep --color '[[]]' infileThere will be no match, none at all. You need this to get it working correctly:$ grep --color '[][]' infilelist[1]; i[ab1]; var[1][1]var[1]var[2]In that specific order, the closing brace must be the first character inside the character range. The opening brace must be the last character in the character list.[]a-z0-9[]Then, you can add other characters (only not the ;):$ grep --color '[]a-z0-9[]' infilelist[1];i[ab1];var[1][1]var[1]var[2]And then, you can add the missing | in the range and do the match that is the link you posted. The regex in that link is not the same as here, and works in a very differnt way. It starts by matching one [, some other characters and end with a closing ]. Something similar to (the greedy nature of the * takes the whole line):$  grep --color '\[.*\]' infilelist[1]; i[ab1]; var[1] [1]var  [1]var[2]Or also similar to this:$ grep --color '[[][a-c0-9]*[]]' infilelist[1]; i[ab1]; var[1][1]var[1]var[2]`