bash-scripting: preserve whitespaces in variables

When you want to store a string like

"abc        def    gh ijk"

in a variable on a linux-shell, you’d be normally faced with this:

bash> VAR1="abc        def    gh ijk"
bash> echo $VAR1
abc def gh ijk
bash>

Your whitespaces are trimmed. This is a problem if you need the exact string e.g. for a string-compare.
The cause of this behaviour is the internal shell variable $IFS (Internal Field Separator), that defaults to whitespace, tab and newline.
Thus the variable $VAR1, when passed over to “echo”, is not seen as one single string but as a bunch of strings separated by whitespaces:

bash> VAR1="abc        def    gh ijk"
bash> for a in $VAR1
> do
> echo $a
> done
abc
def
gh
ijk
bash>

To preserve all contiguous whitespaces you have to set the IFS to something different:

bash> IFS='%'
bash> echo $VAR1
abc        def    gh ijk
bash>
bash> for a in $VAR1; do echo $a; done
abc        def    gh ijk
bash>

Afterwards you can switch back to default with “unset IFS”:

bash>unset IFS
bash>echo $VAR1
abc def gh ijk
bash>

Edit 2014-05-21:
Please read Martin’s advice and my reply on it below for another approach.

Advertisements

7 Responses to bash-scripting: preserve whitespaces in variables

  1. Bryan says:

    Thank you!! This was killing me, and you have solved my problem.

  2. SAWells says:

    I second Bryan’s comment completely. The world must know about this. Tell everybody.

  3. indica says:

    OH MY GOD>:)))) Thank you, you genius!

    I Third Bryan’s comment and Second SAWells comment! 😀

  4. I can’t believe I’ve wasted TWO days because of this CRAP!

    I knew BASH was manipulating my strings without my contentment, but I didn’t find ways around it other then ECHO ” ” (one space) in a loop!!! Thank you very much for the solution!

    Anyway… Who was the GENIUS that decided to develop BASH with this stupid “behavior”? It should be quite the opposite: when we need it, IF we ever need it, then we activate it (as an extra feature, at most)!

    The contents of a STRING is sacred. What is placed in between the quotes is there because it needs to be there. Period! Anyone (or anything) working against it must rot in hell!!! 😛

  5. Martin says:

    What’s the problem with just quoting the string before echoing it?

    bash>VAR1=”abc def gh ijk”
    bash>echo “$VAR1”
    abc def gh ijk

    @Julio: bash is not manipulating the string; it’s the word splitting that occurs when you pass the string unquoted to echo. Word splitting is an essential function of the shell; if it didn’t do that, you wouldn’t be able to pass more than a single argument to any command.

    • Bryan says:

      Martin, the problem is if you want to preserve more than one space between abc and def. Try it.

    • logbuffer says:

      @Martin: I was sure, I tested my case with quoted strings – as it’s so obvious. But apparently I did not. I just tested it again on your advice. And lo and behold, it works.
      I think my problem back then was like this:

      bash> VAR1="abc        def    gh ijk"
      bash> VAR2=`echo "somestring "$VAR1" somestring"`
      bash> echo "$VAR2"
      somestring abc def gh ijk somestring
      

      I didn’t mind to double the double-quotes around the variable like this:

      bash> VAR2=`echo "somestring ""$VAR1"" somestring"`
      bash> echo "$VAR2"
      somestring abc        def    gh ijk somestring
      

      @Bryan: I think Martin had used my example as above – including all whitespaces. I suppose it’s WordPress what trimmed the whitespaces this time. 😉

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: