6

I want to replace TABs in stdout with semicolons, by running sed from the ZSH shell.

I understand one can normally (in other shells?) use:

somecommand | sed 's/\t/;/g'

However, this doesn't work for me in ZSH-shell under FreeBSD. The \t doesn't match the tabulators. Why is this? I've also tried multiple backslashes (up to 5).


This does work:

somecommand | sed 's/[TAB]/;/g'

, where [TAB] is an actual TAB-character, inserted by entering Ctrl-V followed by the TAB button on my keyboard.

tripleee
  • 175,061
  • 34
  • 275
  • 318
poplitea
  • 3,585
  • 1
  • 25
  • 39

3 Answers3

8

Use of zsh has nothing to do with it. The \t is a GNU extension to the regular expressions used in sed. On a BSD sed, you don't have the extensions, so have to use the literal tab.

Michael J. Barber
  • 24,518
  • 9
  • 68
  • 88
  • 10
    @poplitea If your script will only run in ksh93, bash or zsh (as opposed to other sh variants such as pdksh, Bourne or ash), then you can use `$'s/\t/;/'g` where the shell does the backslash expansion and `sed` sees a literal tab character. – Gilles 'SO- stop being evil' Dec 07 '11 at 22:35
  • @Gilles: Fantastic! I knew of $(), but not of $'' substitution. Thank you very much, this makes it easy solving my problem. You should probably have put this in an answer rather than a comment, though(?). – poplitea Dec 08 '11 at 14:06
3

One option is to prepare your sed script ahead of time with printf.

scr="`printf 's/\t/;/g'`"
somecommand | sed "$scr"

But Michael++... There may be other sed variants that also support printf-style escapes, but it's certainly not "standard".

ghoti
  • 45,319
  • 8
  • 65
  • 104
0

If you know the output of the command is normal text (only tabs & printable text), you could use:

somecommand | sed -E 's/[[:cntrl:]]/;/g'

-E turns on "extended" regular expressions, which can contain character class names.

jeberle
  • 718
  • 3
  • 15