I tried sed -i '/^/d' myfile
and it deleted the entire file. How to avoid this? I want to remove all lines with ^
in it.
-
This had been answered in: http://stackoverflow.com/questions/5410757/delete-lines-in-a-text-file-that-containing-a-specific-string Eventually read also: http://stackoverflow.com/questions/407523/escape-a-string-for-a-sed-replace-pattern – PawelSz Jul 17 '16 at 01:35
-
My question was with a carat, not a character, but my title was changed. – Pete Jul 17 '16 at 01:41
-
My bad, already undone. Anyway, maybe the title can be changed to 'special character' to make it more generic? – pah Jul 17 '16 at 01:47
-
@Pete If you saw the ^ mark in vi,that means the ^ with something is an special character, not the literal ^. You better consider edit you question. – Ekeyme Mo Jul 17 '16 at 02:08
-
Please note that the char. in question is spelled [_caret_](https://en.wikipedia.org/wiki/Caret), not [carat](https://en.wikipedia.org/wiki/Carat_(mass)). – mklement0 Jul 17 '16 at 02:35
2 Answers
In regular expressions, characters that are "special" lose their special meaning when they exist within a bracket expression (square brackets). So you'd think that a search for [^]
would be what you need.
Alas, it turns out that while this works for the caret, the caret also gains a different special meaning when it is the first character of a bracket expression. It is used to negate the expressions. So [^]
is actually invalid regex syntax, and this character still needs to be escaped.
What you're looking for, in GNU sed, might look like:
sed -i '/[\^]/d' myfile
This looks awkward (especially when compared to @threadp's answer), but I prefer the square bracket approach to escape specials because it works on all other special characters the same way and its behaviour is consistent across regex parsers. Backslashes are used for other things -- continuing lines in shell scripts, converting characters to specials (\n
, \t
, etc). Too many backslashes can make things confusing.
One interesting thing to note is that the caret is only special within a bracket expression if it is the FIRST character. So the following works:
$ printf 'one\ntwo^\n' | sed -ne '/[X^]/p'
two^

- 45,319
- 8
- 65
- 104
-
1I like the `[ ]` approach in general, but in the specific case of `^` I'm not so sure, because `^` is also a special character when it's the first character in a character class. – ruakh Jul 17 '16 at 02:26
-
Good point in general, but `^` is actually the - one and only - char. that needs escaping even inside a character set _as the 1st character_, given that it does have special meaning there: to negate the character set/ranges formed by the remaining characters; thus, you actually do need `[\^]` in this case. – mklement0 Jul 17 '16 at 02:27
-
An amended form or your recommendation: escape `^` as `\^`, which works in ALL regex dialects; put _any other chars._ you want to be treated as literals inside `[...]`, but, if applicable, place `-` at the _end_, so as to avoid _its_ special interpretation inside a character set (as a _range_ operator). – mklement0 Jul 17 '16 at 02:33
-
1@mklement0, wow, it's not often that I make an error like that with sed or regex. Thanks for highlighting this and providing your clear explanation, I'll correct my answer. – ghoti Jul 17 '16 at 04:19