sh: manipulating tab in var

This is hardcoded var in my sh script
Code:
# 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:
Code:
# 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.
 
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):
Code:
#!/bin/sh
lol="do co\tle\t\ttsk"
lol=`printf "$lol"`
echo "$lol"

There's also expand(1).
 
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):
Code:
#!/bin/sh
lol="do co\tle\t\ttsk"
lol=`printf "$lol"`
echo "$lol"

There's also expand(1).

Thank you for your effort.
However, starting point must be: (contains real tabs)
Code:
lol='do co	le		tsk'
Then turned into:
Code:
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:
Code:
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.
 
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:
Code:
#!/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 said:
Code:
lol='do co	le		tsk'
printf "$lol" | sed 's/	/\\t/g'

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

printf '%s' "$lol" | sed "s/$TAB/\\\\t/g"
 
jilles@ said:
To avoid problems with backslashes and percent signs and improve readability, instead do:
Code:
TAB=$(printf '\t')

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

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.
 
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!
 
Back
Top