Case-insensitive search and replace with sed
case-insensitive, macos, replace, sed
Solution
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 report 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.
Problem
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?