Why is sed not recognizing \t as a tab? Why is sed not recognizing \t as a tab? bash bash

Why is sed not recognizing \t as a tab?


Not all versions of sed understand \t. Just insert a literal tab instead (press Ctrl-V then Tab).


Using Bash you may insert a TAB character programmatically like so:

TAB=$'\t' echo 'line' | sed "s/.*/${TAB}&/g" echo 'line' | sed 's/.*/'"${TAB}"'&/g'   # use of Bash string concatenation


@sedit was on the right path, but it's a bit awkward to define a variable.

Solution (bash specific)

The way to do this in bash is to put a dollar sign in front of your single quoted string.

$ echo -e '1\n2\n3'123$ echo -e '1\n2\n3' | sed 's/.*/\t&/g't1t2t3$ echo -e '1\n2\n3' | sed $'s/.*/\t&/g'    1    2    3

If your string needs to include variable expansion, you can put quoted strings together like so:

$ timestamp=$(date +%s)$ echo -e '1\n2\n3' | sed "s/.*/$timestamp"$'\t&/g'1491237958  11491237958  21491237958  3

Explanation

In bash $'string' causes "ANSI-C expansion". And that is what most of us expect when we use things like \t, \r, \n, etc. From: https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html#ANSI_002dC-Quoting

Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded...

The expanded result is single-quoted, as if the dollar sign had not been present.

Solution (if you must avoid bash)

I personally think most efforts to avoid bash are silly because avoiding bashisms does NOT* make your code portable. (Your code will be less brittle if you shebang it to bash -eu than if you try to avoid bash and use sh [unless you are an absolute POSIX ninja].) But rather than have a religious argument about that, I'll just give you the BEST* answer.

$ echo -e '1\n2\n3' | sed "s/.*/$(printf '\t')&/g"    1    2    3

* BEST answer? Yes, because one example of what most anti-bash shell scripters would do wrong in their code is use echo '\t' as in @robrecord's answer. That will work for GNU echo, but not BSD echo. That is explained by The Open Group at http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37_16 And this is an example of why trying to avoid bashisms usually fail.