Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Dealing with split

by perl_99_monk (Novice)
on Feb 22, 2006 at 22:09 UTC ( [id://532105]=perlquestion: print w/replies, xml ) Need Help??

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

I have a string that contains one long line in the following format.(ie space seperated files)
c:\temp\source\test\test.c@@main\com\etc c:\temp\source\test\test1.c@@ +main\com\test c:\temp\source\test\test3\test2.c@@main\com\etc\test
I only need the info between c:\temp and @@ ie I want the output to be each on a new line as:
\source\test\test.c \source\test\test1.c \source\test\test3\test2.c
I first tried splitting on the space to get a list of files but id not seem to be working. CAn anyone suggest what is the effective way to do this? THanks

Replies are listed 'Best First'.
Re: Dealing with split
by GrandFather (Saint) on Feb 22, 2006 at 22:20 UTC

    The following does what you want, but it may be over-fussy:

    use strict; use warnings; my @files = split '@@', <DATA>; s/^.*?c:\\temp// for @files; @files = grep {/^\\/} @files; print join "\n", @files; __DATA__ c:\temp\source\test\test.c@@main\com\etc c:\temp\source\test\test1.c@@ +main\com\test c:\temp\source\test\test3\test2.c@@main\com\etc\test

    Prints:

    \source\test\test.c \source\test\test1.c \source\test\test3\test2.c

    DWIM is Perl's answer to Gödel
Re: Dealing with split
by runrig (Abbot) on Feb 22, 2006 at 22:45 UTC
    I'd avoid split in this instance (m//g is more readable IMHO):
    print "$_\n" for /c:\\temp(\S*?)@@/g;
Re: Dealing with split
by dsb (Chaplain) on Feb 22, 2006 at 22:19 UTC
    You can still use split(), you just have to get a bit creative:
    $str = 'c:\temp\source\test\test.c@@main\com\etc c:\temp\source\test\t +est1.c@@main\com\test c:\temp\source\test\test3\test2.c@@main\com\etc +\test'; print map {"$_\n" if s/c:\\temp(.*?\.c)/$1/} split(/\s+|\@+/,$str);
    UPDATE: Thanks to Grandfather for the heads up on interpolation of my \'s. I did this correctly in my tests, but posted it wrong...thanks again.

    SECOND UPDATE: I don't what happened between testing and posting that this code isn't working. It worked fine on my box.

    THIRD AND (hopefully) FINAL UPDATE: Got it now. Thanks again to Grandfather.


    dsb
    This @ISA my( $cool ) %SIG

      You should really test your code before posting. All the \ dissapear from $str - use non-interpolating ' rather than " to fix that.

      There is a missing / in the split regex and an extra ) following it.

      Even after fixing those errors, when the code is run a "Use of uninitialized value in split" warning is issued and incorrect output is generated:

      \source\test\test.c@@main\com\etc c:\temp\source\test\test1.c@@main\co +m\test c:\temp\source\test\test3\test2.c@@main\com\etc\test

      DWIM is Perl's answer to Gödel
      dsb I am using your command and need a little more help. If I want to get all the files that has an extension not just .c how can i specify that? In the command I see that .c is specified. Can I specify mutliple patterns or use a wild card so that it gets all the files with extension.I have few .c files, .java and .xml and some directories in the $str. I just want to filter out the directories and get the files. ie in addition to
      'c:\temp\source\test\test.c@@main\com\etc c:\temp\source\test\test1.xm +l@@main\com\test c:\temp\source\test\test3\test2.c@@main\com\etc\test + c:temp\source c:\temp\source\java@@main\com\etc\test c:temp\source\ +java\test.java@@main\com\etc\test '
      I want the out put to be
      \test\test.c \source\test\test3\test2.c \test\test1.xml \source\java\test.java
      THanks
        You can tweak the regex to match all extensions or feed it an alternation that will find only certain extensions.
        # match any file extension print map {"$_\n" if s/c:\\temp(.*?\.(?:\w|\d)+?)/$1/} split(/\s+|\@+/ +,$str); # match only a few extensions print map {"$_\n" if s/c:\\temp(.*?\.(?:c|xml|java|etc))/$1/} split(/\ +s+|\@+/,$str);
        I think you'd be better of using runrig's snippet at Re: Dealing with split, though.


        dsb
        This @ISA my( $cool ) %SIG
Re: Dealing with split
by Roy Johnson (Monsignor) on Feb 22, 2006 at 22:22 UTC
    my $foo = 'c:\temp\source\test\test.c@@main\com\etc c:\temp\source\tes +t\test1.c@@main\com\test c:\temp\source\test\test3\test2.c@@main\com\ +etc\test'; my @bits = split /\@\@.*?(?: c:\\temp|$)/, $foo; print "$_\n" for @bits;
    Updated as per GrandFather's correction.

    Caution: Contents may have been coded under pressure.

      Doesn't trim off the trailing junk for the last entry:

      c:\temp\source\test\test.c c:\temp\source\test\test1.c c:\temp\source\test\test3\test2.c@@main\com\etc\test

      DWIM is Perl's answer to Gödel
        Thank you all for the suugetions.... It helped me a lot.
Re: Dealing with split
by Praveen (Friar) on Feb 23, 2006 at 07:00 UTC
    Try This
    $str ='c:\temp\source\test\test.c@@main\com\etc c:\temp\source\test\te +st1.c@@main\com\test c:\temp\source\test\test3\test2.c@@main\com\etc\ +test'; while($str=~ m/c:\\temp(.*?)\@\@/g) { print "$1\n"; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://532105]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (6)
As of 2024-03-28 09:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found