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

I have a log file like the one given below
................... ................... <CMD> windowSelect 444.235666.5542.2656565.1255 <CMD> spaceObject -fixSide bottom -space 0 Spacing instances ... Adding vertical channel spacing of 0.0000um between the following selected instances/modules: {dupe_core/pads/tran_w_1} {dupe_core/pads/tran_w_1} {dupe_core/pads/htran_d_13} {dupe_core/pads/rec_p_14} {dup/pads/VDD_ight1} {dup/pa/GND_g} {dummy_core/pads/dummy_dig22} {dupe_core/pads/dummy_dig23} {dupe_core/pads/comp_pad1} {dupe_core/pad/CORE_vdd1} <CMD> deselectAll <CMD> selectInst dummy_core/pads/IO_gnd_right18 <CMD> selectInst dummy_core/pads/IO_vdd_right18 <CMD> uiSetTool move5 .............. ............... ....................
I want to extract the string between the curly bracket eg.From the line {dupe_core/pads/tran_w_1} i need only "dupe_core/pads/tran_w_1" i tried this script with regular expression in perl
$fn = "/home/t8.g"; open FP, "$fn" or die "Error in write:$!"; while (<FP>){ if($_ =~ m/{/g){ $a = $'; if($a =~ m/}/g){ print "Line no. $..Occurence Identified\n"; open FP1, ">>/home/t9.g" or die "Error in write:$!"; print FP1 "$`\n"; close FP1; } } else{ print "Line no. $..No Occurence\n"; } } close FP;
It works except in 1 place, where in a single line 2 times the match is required. i.e., at this line {dup/pads/VDD_ight1} {dup/pa/GND_g} It is giving only "dup/pads/VDD_ight1" and not giving the second match "dup/pa/GND_g" I want it like,
dupe_core/pads/tran_w_1 dupe_core/pads/tran_w_1 dupe_core/pads/htran_d_13 dupe_core/pads/rec_p_14 dup/pads/VDD_ight1 dup/pa/GND_g dummy_core/pads/dummy_dig22 dupe_core/pads/dummy_dig23 dupe_core/pads/comp_pad1 dupe_core/pad/CORE_vdd1
So can any one help me in finishing this task.... thanks in advance

Replies are listed 'Best First'.
Re: Perl Log file extraction help required
by kcott (Archbishop) on Sep 22, 2012 at 07:08 UTC

    G'day renjoooz,

    Welcome to the monastery.

    The special variable $` is not a good choice. I recommend you avoid using it whenever possible. Here's an extract of what perlvar has to say about it:

    "The use of this variable anywhere in a program imposes a considerable performance penalty on all regular expression matches. ..."

    Here's a script (pm_brace_extract.pl) that gives the required output with the input you provided.

    #!/usr/bin/env perl use 5.010; use strict; use warnings; while (<DATA>) { my @caught = /\{([^}]+)/g; next unless @caught; say for @caught; } __DATA__ ................... ................... <CMD> windowSelect 444.235666.5542.2656565.1255 <CMD> spaceObject -fixSide bottom -space 0 Spacing instances ... Adding vertical channel spacing of 0.0000um between the following selected instances/modules: {dupe_core/pads/tran_w_1} {dupe_core/pads/tran_w_1} {dupe_core/pads/htran_d_13} {dupe_core/pads/rec_p_14} {dup/pads/VDD_ight1} {dup/pa/GND_g} {dummy_core/pads/dummy_dig22} {dupe_core/pads/dummy_dig23} {dupe_core/pads/comp_pad1} {dupe_core/pad/CORE_vdd1} <CMD> deselectAll <CMD> selectInst dummy_core/pads/IO_gnd_right18 <CMD> selectInst dummy_core/pads/IO_vdd_right18 <CMD> uiSetTool move5 .............. ............... ....................

    Output:

    $ pm_brace_extract.pl dupe_core/pads/tran_w_1 dupe_core/pads/tran_w_1 dupe_core/pads/htran_d_13 dupe_core/pads/rec_p_14 dup/pads/VDD_ight1 dup/pa/GND_g dummy_core/pads/dummy_dig22 dupe_core/pads/dummy_dig23 dupe_core/pads/comp_pad1 dupe_core/pad/CORE_vdd1

    -- Ken

      Thank you for your help.... I just started learning Perl Scripting... So can u please explain these 3 lines of script...

      my @caught = /\{([^}]+)/g; next unless @caught; say for @caught;

      Updatei tried that script in this way..........................................

      #!/usr/bin/perl $fn = "/home/t8.g"; open FP, "$fn" or die "Error in write:$!"; while (<FP>) { my @caught = /\{([^}]+)/g; next unless @caught; say for @caught; print @caught, "\n"; }
      but i got result as...............................................
      dummy_core/pads/hdmi_tx_1 dummy_core/pads/hdmi_tx_2 dummy_core/pads/hdmi_tx_3 dummycore/pads/hdmi_tx_4 dummy_core/pads/IO_vdd_right25 dummy_core/pads/IO_gnd_right2dummy_core/pads/dummy_dig22 dummy_core/pads/dummy_dig23 dummy_core/pads/comp_pad1 dummy_core/pad/CORE_vdd1

      I am getting that 2 occurrence line in a single line.... Can you please update it.....

        I certainly don't mind explaining but perhaps you could be a bit more specific regarding what's causing you problems.

        The regexp looks for an opening brace (\{) followed by 1 or more characters that are not a closing brace ([^}]). See perlre.

        If no matches were found, the next line of input is read. See next and unless.

        Loop through what was captured and output. See say and for.

        All the documentation links I've provided here are to pages on http://perldoc.perl.org/. I have that link bookmarked and use it often: I suggest you do the same.

        It's good that you're wrapping your code and data in <code>...</code> tags. It's less good that you're wrapping everything in these tags. If it's not code or data, paragraph tags (<p>...</p>) are usually more appropriate. Take a look at Writeup Formatting Tips.

        -- Ken

        If you are not useing perl 5.010 'use 5.010' then mabe this will work.

        #!/usr/bin/env perl #use 5.010; use strict; use warnings; while (<DATA>) { my @caught = /\{([^}]+)/g; next unless @caught; #say for @caught; foreach (@caught){print $_."\n"}; } __DATA__ ................... ................... <CMD> windowSelect 444.235666.5542.2656565.1255 <CMD> spaceObject -fixSide bottom -space 0 Spacing instances ... Adding vertical channel spacing of 0.0000um between the following selected instances/modules: {dupe_core/pads/tran_w_1} {dupe_core/pads/tran_w_1} {dupe_core/pads/htran_d_13} {dupe_core/pads/rec_p_14} {dup/pads/VDD_ight1} {dup/pa/GND_g} {dummy_core/pads/dummy_dig22} {dupe_core/pads/dummy_dig23} {dupe_core/pads/comp_pad1} {dupe_core/pad/CORE_vdd1} <CMD> deselectAll <CMD> selectInst dummy_core/pads/IO_gnd_right18 <CMD> selectInst dummy_core/pads/IO_vdd_right18 <CMD> uiSetTool move5 .............. ............... ....................
Re: Perl Log file extraction help required
by protist (Monk) on Sep 22, 2012 at 12:08 UTC
    just to illustrate a different approach:
    $fn = "/home/t8.g"; open $fp, "<",$fn" or die "Error in write:$!"; while (<$fp>){ print $1 while $_=~s/{(.*?)}//; }
    Here is a one liner for you to see it in action. This takes user input.
    perl -ne 'print $1."\n" while $_=~s/{(.*?)}//;'