0

I have a block of text I'm trying to edit like this, in a script:

First, I tried

VAR2=`echo $VAR | sed 's/\n/\n\t/g'

It removes the newlines, but doesn't add the newline or tab back in.

Is this some stupid mistake? Not escaping something I should?

krb686
  • 1,570
  • 8
  • 23
  • 44
  • 1
    Are you trying to add tabs at the begining of each line in the fle? – nu11p01n73R Mar 06 '15 at 14:59
  • 1
    That doesn't remove newlines at all. `echo $VAR2` will make it look like it does though. `sed` can't normally operate on newlines because they are already not there when your actions operate. – Etan Reisner Mar 06 '15 at 15:01
  • In vim, the inserted newline needs to be `\r`. Not sure if the same is true for `sed`. http://stackoverflow.com/questions/71323/how-to-replace-a-character-for-a-newline-in-vim – QuestionC Mar 06 '15 at 15:12
  • Yes, attempting to add a tab at the beginning of each line of a block of text – krb686 Mar 06 '15 at 15:34

1 Answers1

2

Two things:

  1. You have to prevent shell expansion of $VAR, or the newlines will be lost before you have a chance to handle them
  2. sed works in a line-based manner. It treats every line individually, and it doesn't see the newlines between them (unless you do special things).

The first can be handled by quoting $VAR, the second problem I would circumvent by reformulating the problem as "insert a tab to the beginning of every line but the first." That leaves us with:

VAR2=$(echo "$VAR" | sed '1!s/^/\t/')

Where the sed code means: Under the condition 1! (which is the case when we're not handling the first line), do s/^/\t/ -- i.e., replace the empty string at the beginning of the line with a tab.

Note that to look at the result of the substitution, you'll have to quote it as well, or it'll be shell-expanded, and the inserted whitespaces will be lost. That is to say,

echo "$VAR2"

will show the result you want, while

echo $VAR2

will lose all formatting (and potentially do silly things, if there are special characters such as $ in the paragraph).

Wintermute
  • 39,646
  • 4
  • 64
  • 71
  • So is it just a general rule that shell expansion removes newlines? Or how would I know when to double quote a var I am echoing and then piping? Earlier in my script, I used `hostname` and echoed the result without double-quoting to grep and successfully found what I was looking for. – krb686 Mar 06 '15 at 15:57
  • 1
    It's not that shell expansion removes newlines, it's that it splits things into tokens that are passed to the command as individual parameters. You can see this at work when you call `echo foo bar` (with several spaces between the `foo` and `bar`) and get `foo bar` (with only one space) in return: `echo` never sees the whitespace characters that were originally between them, it just sees: "oh, I was called with two arguments `foo` and `bar`, better print them." Double-quoting the variable prevents this splitting from happening, and then echo sees one parameter with embedded whitespace. – Wintermute Mar 06 '15 at 16:03
  • There's an asterisk here about shell-builtins that technically see these things but ignore them to behave like normal commands, but it's not terribly important at the moment. – Wintermute Mar 06 '15 at 16:04