zappee
zappee

Reputation: 22698

sed swallows whitespaces while inserting content

I am trying to insert a new line before the first match with sed. The content that I wanna insert starts with spaces but sed or bash swallows the whitespaces.

hello.txt

line 1
line 2
line 3

The content to insert in my case coming from a variable this way:

content="   hello"

The command that I have created:

sed -i "/line 2/i $content" hello.txt

Result:

line 1
hello
line 2
line 3

Expected result:

line 1
   hello
line 2
line 3

It seems that bash swallows the whitespaces. I have tried to use quotes around the variable this way: sed -i "/line 2/i \"$content\"" but unfortunately it does not work. After playing with this for 2 hours I just decided that I ask help.

Upvotes: 1

Views: 39

Answers (3)

glenn jackman
glenn jackman

Reputation: 246877

would work well here:

ed hello.txt <<END_ED
/line 2/i
$content
.
wq
END_ED

Upvotes: 0

Shawn
Shawn

Reputation: 52449

That's how GNU sed works, yes - any whitespace between the command i and the start of text is eaten. You can add a backslash (At least, in GNU sed; haven't tested others) to keep the spaces:

$ sed "/line 2/i \\$content" hello.txt
line 1
   hello
line 2
line 3

POSIX sed i always requires a backslash after the i and then a newline with the text to insert on the next line (And to insert multiple lines, a backslash at the end of all but the last), instead of the one-line version that's a GNU extension.

sed "/line 2/i\\
$content
" hello.txt

I don't have a non-GNU version handy to test, so I don't know if the leading whitespace in the variable will be eaten, but I suspect not.

Upvotes: 1

Alexis Wilke
Alexis Wilke

Reputation: 20741

You need to use a backslash instead:

content="\    hello"

Otherwise, it's viewed as part of the separated between the /i and the hello.

Note also that the $content variable could end up including all sorts of characters that sed would interpret differently... so be careful.

Upvotes: 0

Related Questions