# sh: manipulating tab in var



## Seeker (Sep 28, 2010)

This is hardcoded var in my sh script

```
# White spaces are:
# do<SPACE>co<TAB>le<TAB><TAB>tsk
lol='do co	le		tsk'
```
Now, I would like to parse string, in that var, to get redefined $var with value:

```
# White space <TAB> char, is substituted with 2 chars: \t
lol='do co\tle\t\ttsk'
```
Using sh's built in 'echo' for piping it to 'converter' is a no go, as echo replaces tab with space BEFORE output-ing.


----------



## wblock@ (Sep 29, 2010)

Use printf(1) to convert \t into tabs, then quote your arguments to echo to keep it from being stupid smart about parameter parsing (tested):

```
#!/bin/sh
lol="do co\tle\t\ttsk"
lol=`printf "$lol"`
echo "$lol"
```

There's also expand(1).


----------



## Seeker (Sep 29, 2010)

wblock said:
			
		

> Use printf(1) to convert \t into tabs, then quote your arguments to echo to keep it from being stupid smart about parameter parsing (tested):
> 
> ```
> #!/bin/sh
> ...



Thank you for your effort.
However, starting point must be: (contains real tabs)

```
lol='do co	le		tsk'
```
*Then* turned into:

```
lol="do co\tle\t\ttsk"
```
Not vice versa.

What printf does is, once outputed to console, both variables look same, but those are white spaces populated with spaces *instead* of tabs.
Same can be achieved with:

```
echo -e 'do co\tle\t\ttsk'
```
Which is also faster, as it is sh's built-in command.

You can't even pass <TAB> to console itself by pressing Tab button.
So now, it is logical, why echo filters it, as bourne is built for console level task automation.

I descended from PHP into SH and was puzzled, "what is this, I can't edit file contents, with it", as echo filters almost all white space chars, so I can't pipe reliably.


----------



## wblock@ (Sep 29, 2010)

So you want to convert real tabs (0x09) into "\t".  An easy way to do this is perl, just pipe it into perl -pe 's%\t%\\t%g'.  Shell purists may sneer at that, but it's easier than trying to get sed(1) to do it.  Although I guess you could use tr(1) to map the tab to something sed can handle easily:

```
#!/bin/sh

# create lol with real tabs in it
lol=`printf "do co\tle\t\ttsk"`

# use perl to easily switch tabs back to "\t"
#echo "$lol" | perl -pe 's%\t%\\t%g'

# use tr to change tabs to tilde,
# then use sed to replace tilde with "\t"
# hope you aren't using tilde for anything
echo "$lol" | tr "\t" "~" | sed -e 's%~%\\t%g'
```

Maybe there's an easier way to do that.  sh makes everything harder.


----------



## Beastie (Sep 29, 2010)

```
lol='do co	le		tsk'
printf "$lol" | sed 's/	/\\t/g'
```


----------



## jilles@ (Oct 1, 2010)

Beastie said:
			
		

> ```
> lol='do co	le		tsk'
> printf "$lol" | sed 's/	/\\t/g'
> ```



To avoid problems with backslashes and percent signs and improve readability, instead do:

```
TAB=$(printf '\t')

printf '%s' "$lol" | sed "s/$TAB/\\\\t/g"
```


----------



## wblock@ (Oct 1, 2010)

jilles@ said:
			
		

> To avoid problems with backslashes and percent signs and improve readability, instead do:
> 
> ```
> TAB=$(printf '\t')
> ...



The variable for a tab is more readable than an invisible tab, but now you've got a $ in your search pattern, which looks like end-of-line, and four backslashes.


----------



## Seeker (Oct 1, 2010)

To quote myself ...


			
				Seeker said:
			
		

> Using sh's built in 'echo' for piping it to 'converter' is a no go, as echo replaces tab with space BEFORE output-ing.


*NOT!* I've mistaken, totally!

As long as variable passed to 'echo', is in double quotes, ALL white space chars are preserved and passed to console.
CONSOLE/TERM is one to blame, as IT filters white space chars, which aren't '\n' or 'space', i.e;
'\t' gets replaced, with appropriate amount of spaces, so in console it look like tab is working.

I had to use hexdump to see this and this is not in a sh's man pages.

As for "injecting" real tab in $var, 'printf' is a cleaner way, as it doesn't append newline, as 'echo -e' does(can't be avoided with '-n')

Crew..., thx for help_!_


----------

