How do I say \"is not\" a certain character in sed
?
From my own experience, and the below post supports this, sed doesn't support normal regex negation using "^". I don't think sed has a direct negation method...but if you check the below post, you'll see some workarounds. Sed regex and substring negation
[^x]
This is a character class that accepts any character except x
.
For those not satisfied with the selected answer as per johnny's comment.
'su[^x]' will match 'sum' and 'sun' but not 'su'.
You can tell sed to not
match lines with x
using the syntax below:
sed '/x/! s/su//' file
See kkeller's answer for another example.
There are two possible interpretations of your question. Like others have already pointed out, [^x]
matches a single character which is not x
. But an empty string also isn't x
, so perhaps you are looking for [^x]\|^$
.
Neither of these answers extend to multi-character sequences, which is usually what people are looking for. You could painstakingly build something like
[^s]\|s\($\|[^t]\|t\($\|[^r]\)\)\)
to compose a regular expression which doesn't match str
, but a much more straightforward solution in sed
is to delete any line which does match str
, then keep the rest;
sed '/str/d' file
Perl 5 introduced a much richer regex engine, which is hence standard in Java, PHP, Python, etc. Because Perl helpfully supports a subset of sed
syntax, you could probably convert a simple sed
script to Perl to get to use a useful feature from this extended regex dialect, such as negative assertions:
perl -pe 's/(?:(?!str).)+/not/' file
will replace a string which is not str
with not
. The (?:...)
is a non-capturing group (unlike in many sed
dialects, an unescaped parenthesis is a metacharacter in Perl) and (?!str)
is a negative assertion; the text immediately after this position in the string mustn't be str
in order for the regex to match. The +
repeats this pattern until it fails to match. Notice how the assertion needs to be true at every position in the match, so we match one character at a time with .
(newbies often get this wrong, and erroneously only assert at e.g. the beginning of a longer pattern, which could however match str
somewhere within, leading to a "leak").