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

hey guys , my input look like this:
" -IE:\david\nbssbts\btsc\bld -IE:\david\nbsscis\dcsapp\bld \ --cxx_include_directory C:\Green\scxx -IC:\Green\scxx \ -IC:\Green\68000\include -IC:\Green\ansi \ "
I need to capture the -I only and make it look like this :
" -IE:\david\nbssbts\btsc\bld -IE:\david\nbsscis\dcsapp\bld -IC:\Green\scxx -IC:\Green\68000\include -IC:\Green\ansi "
Now I am able to capture the -I but they don't appear in different line also the main problem is it will capture the "--cxx_include_directory" which I don't need.

my code is

if (index ($_, "-I") == 1){ { print OUTFILE substr ($_, 0, rindex ($_, "\\")), "\n"; } }

Edit by tye

Replies are listed 'Best First'.
Re: New to perl ,,, help
by kvale (Monsignor) on Jun 26, 2002 at 17:00 UTC
    This doesn't answer your perl question, but is hopefully helpful advice.

    First, "New to perl" doesn't describe your problem. To get a better response, try creating a more descriptive title, such as "Parsing makefiles" or "Extracting path names from a text file".

    Second, you have posted your last several questions in the wrong section. If you post quick questions like the above in Seekers of Perl Wisdom, you will get a better response. Thanks,

    -Mark
Re: Transforming only parts of input
by Aristotle (Chancellor) on Jun 26, 2002 at 17:36 UTC

    What your code is doing is printing the entire line (substr $_, 0,) up to but excluding the last backslash. Obviously that's not what you want.

    What you need is a regex. /\B(-I\S+)/ will deliver your desired bits in $1, ready to be printed. You need a /g modifier to catch all matches and iterate over them via while. print "$1\n" while /\B(-I\S+)/g; ____________
    Makeshifts last the longest.
Re: Transforming only parts of input
by GhodMode (Pilgrim) on Jun 26, 2002 at 17:46 UTC
    This way works...
    my @values; while (<>) { my $line = $_; my @elements = split( /\s/, $line ); for ( @elements ) { if ( /(-I.:.*)/ ) { push (@values, $1) }; } } for ( @values ) { print "$_\n" };
         It uses part of Aristotle's idea with the reference to the first grouped part of the regular expression ($1).
         I couldn't get Aristotle's way to work, but I think it's because I always "use strict".

    GM
      Aristotle's idea works fine for me.
      use strict; my @input = split /\n/, ' -IE:\david\nbssbts\btsc\bld -IE:\david\nbsscis\dcsapp\bld \ --cxx_include_directory C:\Green\scxx -IC:\Green\scxx \ -IC:\Green\68000\include -IC:\Green\ansi \ '; foreach (@input) { print "$1\n" while /\B(-I\S+)/g; } ___OUTPUT___ -IE:\david\nbssbts\btsc\bld -IE:\david\nbsscis\dcsapp\bld -IC:\Green\scxx -IC:\Green\68000\include -IC:\Green\ansi
      Of course this will not work if there are embedded spaces in the path names.

      Update --
      To handle embedded spaces use a zero-width lookahead.

      use strict; $_ = ' -IE:\david\nbssbts\btsc\bld -IE:\david\nbsscis\dcsapp\bld \ --cxx_include_directory C:\Green\scxx -IC:\Green\scxx \ -IC:\Green\68000\include -IC:\Green\ansi \ -ID:\Path with spaces\include \ '; s/\\\n//g; print "$1\n" while /(-I.+?(?= -I| --c|$))/g; __OUTPUT__ -IE:\david\nbssbts\btsc\bld -IE:\david\nbsscis\dcsapp\bld -IC:\Green\scxx -IC:\Green\68000\include -IC:\Green\ansi -ID:\Path with spaces\include

      --

      flounder

      There's nothing in my code that violates strict, so I don't know why that would presumably be a problem. Try

      perl -Mstrict -wne'print "$1\n" while /\B(-I\S+)/g;' infile which is the same as
      #!/usr/bin/perl -w use strict; while(<>) { print "$1\n" while /\B(-I\S+)/g; }
      As a minor point, you preferrably want to split on \s+.

      Makeshifts last the longest.