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

hello folks , I have this file with this data :
\nbsstools\i95\src\i95val.h@@\main\golden\2 \nbsstools\i95\src\i95val.cxx@@\main\golden\2 \nbsstools\rlp\src\rlpval.cxx@@\main\golden\3 \nbsstools\rlp\src\rlpval.h@@\main\golden\3 source file(s) -- 4 \nbsscallpmsg\acl\src@@\main\golden\4 \nbsscallpmsg\acl\src\aclpi.h@@\main\golden\1 \nbsscallpmsg\acl\src\aclpi.cxx@@\main\golden\1 \nbsssbs\appl\src@@\main\golden\4 \nbsssbs\appl\src\radiomeasurements.h@@\main\golden\1 \nbsssbs\appl\src\radiomeasurements.cxx@@\main\golden\1
I need to grep the .cxx files only and send them to another file , so my new file will have somthing like this :
i95val.cxx rlpval.cxx aclpi.cxx radiomeasurements.cxx
then from the new file , I just need to build each file at once , so somhting like build i95val.cxx thanks for ideas or tips.

2002-07-03 Edit by Corion : Moved to SoPW, added formatting

Replies are listed 'Best First'.
Re: grep from file
by Kanji (Parson) on Jul 03, 2002 at 16:17 UTC

    You could use grep and s with a funky regex, but I think map would be simpler...

    my @cxx = map { /(\w+\.cxx)@@/ ? ($1) : () } <FILE>;

    Although, if all you're going to do with @cxx is print it out to a new file, you can avoid building a temporary array with something like...

    print NEWFILE map { /(\w+\.cxx)@@/ ? ("$1\n") : () } <FILE>;

        --k.


      Some additional notes: it actually gets even simpler. my @cxx = map /(\w+\.cxx)@@/, <FILE>; Lines that don't match will not return anything, so they simply fall through the cracks. Lines that match return a list of captured strings, of which there's only one here, so we get exactly what we want. For the latter snippet I'd advise using <> so that you can take input from an arbitrary number of files or optionally from STDIN. By printing to STDOUT the user can redirect output to wherever he wants, including piping to another command. Not only is this much more flexible, you can also skip typing out a lot of file interaction and error checking code. The entire script is now reduced to a single line: print map /(\w+\.cxx)@@/, <>; That's all it takes. Pass it to perl -e and you have a perfect oneliner. :)

      Makeshifts last the longest.

Re: grep from file
by flounder99 (Friar) on Jul 03, 2002 at 16:27 UTC
    I think this will do what you want.
    use strict; open (INFILE, "<infile") or die "could not open file"; my %files; while (<INFILE>) { foreach ( /(\w+\.cxx)\b/g ) { $files{$_}++; } } close INFILE; open (OUTFILE, ">outfile") or die "could not open file"; foreach (sort keys %files) { print OUTFILE "$_\n"; } close OUTFILE;
    outfile will contain
    aclpi.cxx i95val.cxx radiomeasurements.cxx rlpval.cxx
    Note that the order is not the same. This is due to the fact that I use a hash and the keys function does not give the keys back in any particular order, so I sort them. If you want to do the build-ing in perl then you can do something like this
    foreach (sort keys %files) { system "build", $_; }

    --

    flounder