Case-insensitive search and replace with sed
Another work-around for sed
on Mac OS X is to install gsed
from MacPorts or HomeBrew and then create the alias sed='gsed'
.
If you are doing pattern matching first, e.g.,
/pattern/s/xx/yy/g
then you want to put the I
after the pattern:
/pattern/Is/xx/yy/g
Example:
echo Fred | sed '/fred/Is//willma/g'
returns willma
; without the I
, it returns the string untouched (Fred
).
Editor's note: This solution doesn't work on macOS (out of the box), because it only applies to GNU sed
, whereas macOS comes with BSD sed
.
Capitalize the 'I'.
sed 's/foo/bar/I' file
Update: Starting with macOS Big Sur (11.0), sed
now does support the I
flag for case-insensitive matching, so the command in the question should now work (BSD sed
doesn't reporting its version, but you can go by the date at the bottom of the man
page, which should be March 27, 2017
or more recent); a simple example:
# BSD sed on macOS Big Sur and above (and GNU sed, the default on Linux)
$ sed 's/ö/@/I' <<<'FÖO'
F@O # `I` matched the uppercase Ö correctly against its lowercase counterpart
Note: I
(uppercase) is the documented form of the flag, but i
works as well.
Similarly, starting with macOS Big Sur (11.0) awk
now is locale-aware (awk --version
should report 20200816
or more recent):
# BSD awk on macOS Big Sur and above (and GNU awk, the default on Linux)
$ awk 'tolower($0)' <<<'FÖO'
föo # non-ASCII character Ö was properly lowercased
The following applies to macOS up to Catalina (10.15):
To be clear: On macOS, 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 and 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).)
A note on the relationship of sed
and awk
to the POSIX standard:
BSD sed
and awk
limit their functionality mostly to what the POSIX sed
and
POSIX awk
specs mandate, whereas their GNU counterparts implement many more extensions.