Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,
I have a problem with a text file which I am trying to strip all the tabs out of, and replace with their equivalent space (I know I could probably do this outside of Perl but I'm sure that there must be a way to do it and I not gonna give up till I find it.) The file looks like this :
{some random text} 9.99 9.999 9.999 9.999 9.9999 9.9999 {more text} 9.99 *9.999 *9.999 9.999 9.9999 9.9999 {even more text} 9.99 9.999 9.999 *9.999 *9.9999 *9.9999 ..this goes on for 12 or so columns..
Basically the first two columns, the text and three sig-fig number are fixed, but the following columns sometimes have a *preceding them, and sometimes don't.
All the table is at present tab-delimited.
<nbsp> So, the problem is, how do I strip out the '\t's?
If it weren't for the '*' I could simply use a "s/\t/ \1/g" or something of that nature. But having the *s means in where there is a *, I need one less space than where there isn't one.
So, I tried this:
perl -1 "while (<>) s/\t(\*w+)/ \1/g;s/\t\s(w+)/ \1/g;print}" +myfile
Which did - <bold> absolutely nothing </bold>. The tabs are all still there.
I know I'm probably being a complete retard, but is there an obvious way to do this that I've missed out on?

Thanks,
Mike

Replies are listed 'Best First'.
Re: Conditionally converting tabs to spaces
by lhoward (Vicar) on Jul 03, 2000 at 22:07 UTC
    how about this....
    while(<>){ s/\t/ /g; s/\s\*/\*/g; print; }
Re: Conditionally converting tabs to spaces
by cwest (Friar) on Jul 03, 2000 at 21:43 UTC
    Here's a solution...
    my $tab = 8; while ( <DATA> ) { chomp; my $fixed = join '', map { $_ . ' 'x($tab-length) } split /\t/; print "$fixed\n"; } __DATA__ hello 57 *45 78 there *57 93 *83 dude 78 23 *45
    Enjoy! Update: This code will not work of a field is longer than 8 chars, but the following will:

    ps. I don't think any of the other responses take that for account either, but if I'm wrong, I'll retract that.

    my $fixed = join '', map { $_ . ' 'x(((int(length()/$tab)+1)*$tab)-len +gth) } split /\t/;
    --
    Casey
    
      I like this approach, but it's hard not to use sprintf in this case:
      my $tab = 8; while (<DATA>) { chomp; my @fields = split(/\t/, $_); my $cooked = shift (@fields) . join '', sprintf("-$tab%s", @fields +); print $cooked, "\n"; }
      lhoward's looks more elegant, though. Make it use variable tabstops like so:
      my $tab = 8; s/\t/" " x $tab/ego;
Re: Conditionally converting tabs to spaces
by nardo (Friar) on Jul 03, 2000 at 22:29 UTC
    In addition to lhoward's response, if the text in the first column ends with a tab, you will need to pad the text with spaces so that everything lines up.
    s/^([^\t]*)/sprintf('%-10s', $1)/e;
    will pad it to 10 characters (and will leave the tab).