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

Greetings. I'm trying to "clean up" a text file so it becomes a regular CSV (Character Separated Values) file. My main problem is that the file is separated by several spaces, for an example:

apple   banana   lemon

And what I want is:

apple|banana|lemon

They are NOT tabs, so I need to raplace them. Shouldn't something like tr/ /\|/ work?

I'm really confused here...

Er Galvão Abbott
a.k.a. Lobo, DaWolf
Webdeveloper
  • Comment on Replacing double spaces (was: Reaplcing double spaces)

Replies are listed 'Best First'.
Re: Reaplcing double spaces
by Zaxo (Archbishop) on Sep 23, 2001 at 03:01 UTC

    Here's my favorite way of doing that. The line is assumed in $_:

    join '|', split " ", $_;
    Double-quoted space is magical in split. It eats all whitespace.

    Update: Bah:<code> join '|', split /\s\s/, $_; <code>

    After Compline,
    Zaxo

      I did not fully comprehend what was happening when using " " or ' ' with split. It does indeed use any whitespace ( , \n, \t, \r ) as delimiters. Which made me wonder how you get it for just a single space. Most of you probably know this, but in case someone else was wondering too:

      split / /, $_;

Re: Reaplcing double spaces
by wog (Curate) on Sep 23, 2001 at 03:01 UTC
    In addition to the s/// solution already proposed you can use tr:

    my $str = "apple banana lemon"; $str =~ tr/ /|/s; print "$str\n"; # apple|banana|lemon

    The /s option to tr is needed to do this. It will make tr "squash" repeated characters generated by transliteration to just one character.

Re: Reaplcing double spaces
by blakem (Monsignor) on Sep 23, 2001 at 02:49 UTC
    How about this:
    #!/usr/bin/perl -wT use strict; my $txt = " apple bannana lemon "; print "Before: '$txt'\n"; $txt =~ s/(^\s+)|(\s+$)//g; # remove leading and trailing spaces; $txt =~ s/\s+/\|/g; # collapse multiple spaces into a singl +e '|' print "After: '$txt'\n"; =output Before: ' apple bannana lemon ' After: 'apple|bannana|lemon'

    -Blake

Re: Reaplcing double spaces
by ducky (Scribe) on Sep 23, 2001 at 02:48 UTC

    Hmmm... tr just does translating. ie, First character in the left hand list gets replaced with the first character in the right hand list, etc. Try replacing tr with s and adding "g" to the end. If you've got a variable number of spaces something like: s/ +/|/g should work.

    (see update II) Since it's 2 or more, use this: s/  +/|/gThat's two spaces, then a + to gobble the additional spaces.

    HTH

    -Ducky

    update:Gah! typos galore! =/

    update II:Based on the reply, added a mo' bettah, should work kinda answer.

      Ducky, you're my hero :)

      Thanks a lot, everyone.

      Er Galvão Abbott
      a.k.a. Lobo, DaWolf
      Webdeveloper
      Sorry, guys. I did not made one point very clear:

      I need to replace ONLY two or more spaces. If there is only one space it have to be left the way it is. So, for a new example:

      Apple Pie    Banana Ice    Lemon Juice

      What I need:

      Apple Pie|Banana Ice|Lemon Juice

      Any thoughts?

      Er Galvão Abbott
      a.k.a. Lobo, DaWolf
      Webdeveloper

        Aha! gotcha covered, big guy =) See my reply again for my final answer

        -Ducky

Re: Reaplcing double spaces
by scott (Chaplain) on Sep 23, 2001 at 02:56 UTC

    tr *translates* characters. So, in your example, each and every space becomes a pipe. You want a substitution, s/\s+/\|/. This says take each group of spaces (\s+) and replace them with a single pipe (\|). tr/ /\|/ says take each space *as an individual* and replace it with a pipe.

    scott