Tue 08 Nov 2011 06:27:52 PM UTC, comment #1:
I'm closing this as invalid - the only bug here is your mis-understanding of the documentation.
POSIX requires grep to handle Basic Regular Expressions, as defined at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html
In that definition, section 9.3.5 specifies how a bracket expression behaves. Among other things, "The <right-square-bracket> ( ']' ) shall lose its special meaning and represent itself in a bracket expression if it occurs first in the list (after an initial <circumflex> ( '^' ), if any). Otherwise, it shall terminate the bracket expression, unless it appears in a collating symbol (such as "[.].]" ) or is the ending <right-square-bracket> for a collating symbol, equivalence class, or character class. The special characters '.' , '*' , '[' , and '\\' ( <period>, <asterisk>, <left-square-bracket>, and <backslash>, respectively) shall lose their special meaning within a bracket expression."
Thus, "^[^\]]*$' is the regular expression that searches for beginning of line, followed by any number of characters that match the bracket expression [^\] (basically, any character except backslash), followed by a literal right bracket, followed by end of line, and grep is correctly interpreting this.
If you want to find all lines that don't contain ], then use the regular expression "^[^]]$", which is the beginning of line, followed by the bracket expression [^]] (any number of non-right-bracket characters), followed by end of line.
Your "counterexample" of "^[^\[]*$" was not all lines that don't contain [, but rather all lines that contain neither [ nor backslash.
Other things to think about: why not use grep -v to invert which lines are printed? By doing that, you no longer have to use ^, *, or $, since a single ] anywhere in the line excludes that entire line:
ls | grep -v ]
Also, ls | grep is inefficient, especially if you want directory recursion. You may want to consider using find for the job, especially since that gives you recursion capabilities (although then you are dealing with globs rather than BRE):
find . ! -name ']'
|