ManInMoon
ManInMoon

Reputation: 7005

How do I convert tabs to exact number of spaces in bash script?

I need to convert a string with tabs to a string with spaces.

But I need to number of spaces to match the tabbing so that the format is identical.

I need this because Gnuplot labels don't like tabs.

So I want:

A      very       fat      cat

Which is A\tvery\tfat\tcat, converted to:

A      very       fat      cat

with spaces, and not to

A very fat cat

EDIT 1

I think I misunderstood the problem:

$ cat -T Aggregate/summary.txt | head -n1
      Date        Pnl     AnnPnl  Days  AvTrds  AveVol  AveDur TDays      Pnl/$  AvPnl     StdDev       MAXD  Shrpe

But when I assign to a variable the spaces are lost:

$ FF=`cat Aggregate/summary.txt | head -n1`; echo $FF
Date Pnl AnnPnl Days AvTrds AveVol AveDur TDays Pnl/$ AvPnl StdDev MAXD Shrpe

Upvotes: 2

Views: 183

Answers (3)

repzero
repzero

Reputation: 8402

UNDERSTANDING WHY YOUR TAB SPACES ARE CONVERTED INTO SINGLE SPACE CHARS

Let us rename your variable to "variable" and assign the following to it

variable ="      Date        Pnl     AnnPnl  Days  AvTrds  AveVol  AveDur TDays      Pnl/$  AvPnl     StdDev       MAXD  Shrpe"

[1] when you do

echo $variable

your output will be

Date Pnl AnnPnl Days AvTrds AveVol AveDur TDays Pnl/$ AvPnl StdDev MAXD Shrpe

Reason: echo is seeing your variable not as one big string but several strings spearated by a space or more than one space character.This is because bash is not seeing this variable as one string since the variable is not enclosed in double qoutes.

[2] when you do

 echo "$variable"

your output will be

      Date        Pnl     AnnPnl  Days  AvTrds  AveVol  AveDur TDays      Pnl/$  AvPnl     StdDev       MAXD  Shrpe

Reason: This is because you enclose your variable with double quotes which bash will automatically interpret as one big string. As a result echo will print this one big string.

Upvotes: 0

Geoff Nixon
Geoff Nixon

Reputation: 4994

There's a utility just for this: expand.
expand [file] (or from standard input) should do the trick.

Re: your edit,

use quoted POSIX-style command substitution rather than backticks:

FF="$(cat Aggregate/summary.txt | head -n1)"; echo "$FF"

Upvotes: 0

fredtantini
fredtantini

Reputation: 16586

You can use the expand command:

~$ cat >c
a       fast    cat     nrstaui e
~$ expand c>d

When using cat -A, you can see that spaces are used (tabs are represented by ^I):

~$ cat -A c
a^Ifast^Icat^Inrstaui^Ie$
~$ cat -A d
a       fast    cat     nrstaui e$

EDIT: If you assign the line to a variable, you have to use double quotes to see the differences:

~$ F=$(cat c)
~$ echo "$F" |cat -A
a^Ifast^Icat^Inrstaui^Ie$
~$ echo $F |cat -A
a fast cat nrstaui e$

Same problem with spaces:

~$ F=$(cat d)
~$ echo "$F" |cat -A
a       fast    cat     nrstaui e$
~$ echo $F |cat -A
a fast cat nrstaui e$

Upvotes: 2

Related Questions