What is the proper way to insert tab in sed?

2020-05-25 07:19发布

问题:

What is the proper way to insert tab in sed? I'm inserting a header line into a stream using sed. I could probably do a replacement of some character afterward to put in tab using regular expression, but is there a better way to do it?

For example, let's say I have:

some_command | sed '1itextTABtext'

I would like the first line to look like this (text is separated by a tab character):

text    text

I have tried substituting TAB in the command above with "\t", "\x09", " " (tab itself). I have tried it with and without double quotes and I can't get sed to insert tab in between the text.

I am trying to do this in SLES 9.

回答1:

You can simply use the sed i command correctly:

some_command | sed '1i\
text    text2'

where, as I hope it is obvious, there is a tab between 'text' and 'text2'. On MacOS X (10.7.2), and therefore probably on other BSD-based platforms, I was able to use:

some_command | sed '1i\
text\ttext2'

and sed translated the \t into a tab.

If sed won't interpret \t and inserting tabs at the command line is a problem, create a shell script with an editor and run that script.



回答2:

Assuming bash (and maybe other shells will work too):

some_command | sed $'1itext\ttext'

Bash will process escapes, such as \t, inside $' ' before passing it as an arg to sed.



回答3:

As most answers say, probably literal tab char is the best.

info sed saying "\t is not portable." :

... '\CHAR' Matches CHAR, where CHAR is one of '$', '*', '.', '[', '\', or '^'. Note that the only C-like backslash sequences that you can portably assume to be interpreted are '\n' and '\'; in particular '\t' is not portable, and matches a 't' under most implementations of 'sed', rather than a tab character. ...



回答4:

Sed can do this, but it's awkward:

% printf "1\t2\n3\t4\n" | sed '1i\\
foo bar\\
'
foo bar
1   2
3   4
$

(The double backslashes are because I'm using tcsh as my shell; if you use bash, use single backslashes)

The space between foo and bar is a tab, which I typed by prepending it with CtrlV. You'll also need to prepend the newlines inside your single quotes with a CtrlV.

It would probably be simpler/clearer to do this with awk:

$ printf "1\t2\n3\t4\n" | awk 'BEGIN{printf("foo\tbar\n");} {print;}'


回答5:

To illustrate the fact the BRE syntax for sed does mention that \t is not portable, Git 2.13 (Q2 2017) gets rid of it.

See commit fba275d (01 Apr 2017) by Junio C Hamano (gitster).
(Merged by Junio C Hamano -- gitster -- in commit 3c833ca, 17 Apr 2017)

contrib/git-resurrect.sh: do not write \t for HT in sed scripts

Just like we did in 0d1d6e5 ("t/t7003: replace \t with literal tab in sed expression", 2010-08-12, Git 1.7.2.2), avoid writing "\t" for HT in sed scripts, which is not portable.

-   sed -ne 's~^\([^ ]*\) .*\tcheckout: moving from '"$1"' .*~\1~p'     
+   sed -ne 's~^\([^ ]*\) .*     checkout: moving from '"$1"' .*~\1~p'
                            ^^^^
                             |
                        (literal tab)


回答6:

I found an alternate way to insert a tab by using substitution.

some_command | sed '1s/^/text\ttext\n/'

I still do not know of a way to do it using the insert method.



回答7:

escape the tab character:

sed -i '/<setup>/ a \\tmy newly added line' <file_name>

NOTE: above we have two backslashes (\) first one is for escaping () and the next one is actual tab char (\t)



标签: linux sed