Why doesn't sed pattern matching treat '\t' as a <tab> character?

I have a file with some leading tabs and I tried to convert the tabs to spaces by using sed:

cat test_file | sed -e 's/[\t]/    /g'

It works properly on various flavours of UNIX, but on my Mac (Sierra) it doesn't treat '\t' as an escape for tab (hex 0x09) rather it treats it as two separated characters.

grep properly handles the \t shortcut for tab.


BSD sed follows the POSIX standard for BRE's, see man 7 re_format. In particular the following:

                                             all other special charac-
 ters, including `\', lose their special significance within a bracket
 expression.

Nor is \t treated special (as the tab character) in the pattern.

You have the following options:

# Type a literal tab in the /pattern/ with the keys <control><v><tab>
's/<control><v><tab>/    /g'

# Use a character class within the bracket expression
's/[[:cntrl:]]/    /g'

# Use ansi -c quoting
$'s/\t/    /g'

# Print the tab with printf
"s/$(printf '\t')/    /g"