Case-insensitive search and replace with sed

Craig Walker picture Craig Walker · Dec 10, 2010 · Viewed 68.2k times · Source

I'm trying to use SED to extract text from a log file. I can do a search-and-replace without too much trouble:

sed 's/foo/bar/' mylog.txt

However, I want to make the search case-insensitive. From what I've googled, it looks like appending i to the end of the command should work:

sed 's/foo/bar/i' mylog.txt

However, this gives me an error message:

sed: 1: "s/foo/bar/i": bad flag in substitute command: 'i'

What's going wrong here, and how do I fix it?

Answer

mklement0 picture mklement0 · Oct 15, 2012

To be clear: On macOS - as of Mojave (10.14) - sed - which is the BSD implementation - does NOT support case-insensitive matching - hard to believe, but true. The formerly accepted answer, which itself shows a GNU sed command, gained that status because of the perl-based solution mentioned in the comments.

To make that Perl solution work with foreign characters as well, via UTF-8, use something like:

perl -C -Mutf8 -pe 's/öœ/oo/i' <<< "FÖŒ" # -> "Foo"
  • -C turns on UTF-8 support for streams and files, assuming the current locale is UTF-8-based.
  • -Mutf8 tells Perl to interpret the source code as UTF-8 (in this case, the string passed to -pe) - this is the shorter equivalent of the more verbose -e 'use utf8;'.Thanks, Mark Reed

(Note that using awk is not an option either, as awk on macOS (i.e., BWK awk, a.k.a. BSD awk) appears to be completely unaware of locales altogether - its tolower() and toupper() functions ignore foreign characters (and sub() / gsub() don't have case-insensitivity flags to begin with).)