So the official bash manual states that "For example, the regular expression ‘[0123456789]’ matches any single digit, whereas ‘[^()]’ matches any single character that is not an opening or closing parenthesis,", copied a link at the bottom of this question, for context.
So I tested it every which way I could think of, to try and do the "negate" part of this, but I could not get it to work:
$ cat test
a line
b line
c line
d line
$ grep [^abc] test
a line
b line
c line
d line
$ grep '[^abc]' test
a line
b line
c line
d line
$ grep '[^(abc)]' test
a line
b line
c line
d line
[$ grep [^(abc)] test
bash: syntax error near unexpected token `('
https://www.gnu.org/software/grep/manual/html_node/Character-Classes-and-Bracket-Expressions.html
I was expecting just line D to be shown
CodePudding user response:
[^abc]
matches any character which is not a
, b
, or c
.
It matches a line
because it includes
, l
, i
, n
, and e
, none of which are the excluded characters.
To ensure that no character in the string matches any in the list you would need grep '^[^abc]*$' test
CodePudding user response:
To stick with the bash
tag on the question, here’s a pure Bash option that takes advantage of extglob
(which is mostly enabled by default).
while IFS= read -r line; do
[[ "$line" = *([^abc]) ]] && printf '%s\n' "$line"
done < test