I wrote some unix code that performs arithmetic on my files and spits out a data matrix into analysis.txt (with added headers). However, when I tried to put this code into a script and run the script, the tabs (\t) separate my columns rather than actual whitespace.

Code that works:

for f in */Data/Intensities/BaseCalls/Alignment*/*.bam; do
 echo 'Processing '$f' ... ' 1>&2
 pftot=`samtools view -c $f`
 pfmit=`samtools view -c $f chrM`
 pfratio=`python -c 'print float('$pfmit')/'$pfgen`
 ftot=`samtools view -c -q 30 -F 1536 $f`
 fmit=`samtools view -c -q 30 -F 1536 $f chrM`
 fgen=$((ftot - fmit))
 fratio=`python -c 'print float('$fmit')/'$fgen`
 echo $name'\t'$pftot'\t'$pfmit'\t'$pfgen'\t'$pfratio'\t'$ftot'\t'$fmit'\t'$fgen'\t'$fratio
done | awk 'BEGIN{print 
> Analysis.txt

Code that doesn't work:

for f in */Data/Inten... "the above code"

Run with:

bash Analysis.sh

prints the variables in the last echo line with literal "\t" separators.

I'm rather new, so any suggestions or resources are appreciated.


This line:

echo $name'\t'$pftot'\t'$pfmit'\t'$pfgen'\t'$pfratio'\t'$ftot'\t'$fmit'\t'$fgen'\t'$fratio

will have the \t inserted directly. One can see something similar from a shell prompt via:

$ export name=hello; echo $name'\t'$name'\t'$name hello\thello\thello

If the echo is changed to echo -e then the output will have tabs in it:

$ export name=hello; echo -e $name'\t'$name'\t'$name hello hello hello

From the man page on echo:

-e enable interpretation of backslash escapes

If -e is in effect, the following sequences are recognized:

  \\     backslash

  \a     alert (BEL)

  \b     backspace

  \c     produce no further output

  \e     escape

  \f     form feed

  \n     new line

  \r     carriage return

  \t     horizontal tab

  \v     vertical tab
  • 1
    A much better solution is to use printf, though. – tripleee Jun 16 '17 at 15:54
  • @tripleee, indeed, but I was just following the OP's approach. – KevinO Jun 16 '17 at 15:57
  • Thank you, this clarifies echo and I will try with printf. – Stewart Russell Jun 17 '17 at 17:09

See the bash(1) man page in the BuiltIn Commands section. The -e option is required for echo to interpret escape characters.


Is your interactive shell bash or something else entirely? echo is notoriously nonportable regarding how it handles special character escapes, like \t. In bash, plain echo doesn't expand them, but in e.g. zsh, it seems to.

$ zsh  -c 'echo "foo\tbar"'
foo     bar
$ bash -c 'echo "foo\tbar"'

Bash's echo -e and zsh's echo -E invert the above behaviour.

Also, you probably want to put those variables within quotes:

echo -e "$name\t$pftot\t$etc..."

Of course, the portable solution would be printf:

printf "%s\t%s\t%s..." "$name" "$pftot" "$..."

But its not hard to see why one would want to use echo instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.