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

hi I am having a problem with the script. I cant seem to make the script read between the patterns. Sample DATA: CREATE TABLE TEMP.BIG_TREE ; : : ------- I want the script to read the file from 'CREATE TABLE' to the '-----'
my @array1 = `cat $ARGV[0]`; my @array2 = 'cat $ARGV[1]'; my $read01 = 0; #$i = 'BIG TREE' my $read01 = 0; foreach my $i (@array1){ for(@array2){ chomp($i); $read01++ if $read01; s/./ . /g; if ($_ =~ /CREATE TABLE TEMP.$i/){ $read01 = 1; } $read01 = 0 if (/^----/) ; next if ($read01 == 1); next unless $read01; print "$_"; } }

Replies are listed 'Best First'.
Re: between pattern search not working
by roboticus (Chancellor) on Jan 15, 2015 at 12:44 UTC

    The second line of your program probably doesn't do what you think it does. As for the remainder of the program, I can't make heads or tails of it with your crazy indentation. If you indent your code properly, it makes it easier to figure out what's going on inside, but I don't feel like downloading your code, reformatting it and then debugging it to find out what's happening.

    Since you're trying to get the text between two strings (possibly repeatedly), I'd suggest doing it this way: read the file as a single string, then split it apart at the dashed line. For the remaining lines, ignore any that don't have the create string in it and print everything after the string. Something like this (untested):

    my $text = slurp_file($a_file_name); my @lines = split /^----.*$/, $text; for (@lines) { if (/CREATE TABLE TEMP\.(.*)/) { say $1; } } sub slurp_file { local $/; my $file_name = shift; open my $FH, '<', $file_name or die "$file_name: $!"; return <$FH>; }

    ...roboticus

    Coding with random whitespace is like trying to run a race in clown shoes.

Re: between pattern search not working
by Eily (Monsignor) on Jan 15, 2015 at 12:28 UTC

    There is a construct in perl that actually means "between", it is the range operator '..'.

    open my $handle, "<", $ARGV[0] or die "Couldn't open file: $!"; # safe +r way to open a file for reading. while (<$handle>) { if (/CREATE TABLE/../-----/) # if between CREATE TABLE and ----- { # Some code } }
    See also the way I opened and read from the file, which is both safer and clearer than what you did, (you can still put the lines in an array by doing: my @lines = <$handle>; and then iterate over the array).

    As for the rest of your script, the bad indentation and poor names make it impossible for me to understand what you are trying to achieve. Please name your arrays to indicate what they contain, like @lines, @cats or @groceryList. And if you have to append numbers to the names of your variables, you are probably doing something wrong.

    You do know that s/./ . /g means "replace every character by a space, a dot and a space" don't you?

    You may want to read perlopentut, perlreftut and other tutorials.

      hi The search pattern is between the search string "BIG_TREE" which is part of the create statement and the "----"
      CREATE TABLE TEMP.BIG TREE : : ------ $i = "BIG_TREE" if ($_ =~ /CREATE TABLE TEMP.$i/){ $read01 = 1; } $read01 = 0 if (/^----/) ; next if ($read01 == 1); next unless $read01; print "$_";
      This part of the code is the problem
Re: between pattern search not working
by BillKSmith (Monsignor) on Jan 15, 2015 at 14:22 UTC
    What did you expect? Remove the strange substitution and your processing seems reasonable. (Your logic is unnecessarily complicated, but it seems to do what you ask.)
    use strict; use warnings; #my @array1 = `cat $ARGV[0]`; #my @array2 = 'cat $ARGV[1]'; my @array1 = ("BIG_TREE\n"); my @array2 = ( ' DATA: CREATE TABLE TEMP.BIG_TREE ;', ':', ':', '-------', 'foo', ); my $read01 = 0; foreach my $i (@array1) { for (@array2) { chomp($i); $read01++ if $read01; #s/./ . /g; if ( /CREATE TABLE TEMP\.$i/ ) { $read01 = 1; } $read01 = 0 if (/^----/); next if ( $read01 == 1 ); next unless $read01; print "$_"; } }
    OUTPUT:
    ::
    Bill
      hi how do I make the iterate over a array and then search for the string 1 first through one array2 (between two patterns) and then search for the same string 1 through array3 (between two string patterns) and print the array 1 output and array 2 output one below the other . I tried this but for some reason its iterating over the entire array 2 first for all the array 1 elements and then going through the array 3 for all the array 1 elements.
      my @array1 = `cat $ARGV[0]`; my @array2 = `cat $ARGV[1]`; my @array3 = `cat $ARGV[2]`; my $read01 = 0; my $newone = (); my $name = (); my $read01 = 0; foreach my $i (@array1){ my $j = $i; chomp($i); my $pp1 = () ; my $ff1 = (); my $gg1 = (); for(@array2){ $read01++ if $read01; s/CREATE TABLE/CREATE BREAKTABLES/g; my $read01 = 0; if ( "CREATE BREAKTABLES TEMP.$i") { ($pp1,$ff1) = split(/BREAKTABLES/); $ff1 =~ s/\(//g; $ff1 =~ s/\s+//g; $ff1 =~ s/TEMP\.//g; $name = $i if ($i = $ff1); ## print "name $name \n"; } print "$name $ff1 --- $_"; } #### END array2 my $read02 = 0; for(@array3){ chomp($i); $read02++ if $read02; s/CREATE TABLE/CREATE BREAKTABLES/g; if ( "CREATE BREAKTABLES TEMP.$i") { my ($pp1,$gg1) = split(/BREAKTABLES/); $gg1 =~ s/\(//g; $gg1 =~ s/\s+//g; $gg1 =~ s/TEMP\.//g; $newone = $i if ($i = $gg1); } print "MIRROR $newone $gg1 --- $_"; } }
      I am a non programmer and I having a hard time imagining. Thank you
        You are much more likely to get the answer that you seek if you follow the example of my previous reply. Provide a complete program (including data) so we all can run it and duplicate your problem. Show the output that it produces and the output that you want. Explain the difference. We do not care what indenting scheme you use, but please be consistent!
        Bill
        @array1='TABLE1','TABLE2'
        file1 data : CREATE TABLE TEMP.TABLE1 : : : ------- CREATE TABLE TEMP.TABLE2 : : : -------
        file2 data : CREATE TABLE TEMP.TABLE1 : : : ------- CREATE TABLE TEMP.TABLE2 : : : -------
        No I want the script to go through the tables in array1 and then through the file1 and file2 and pruduce the output like
        FILE1 : CREATE TABLE TEMP.TABLE1 : : : ------- FILE2 : CREATE TABLE TEMP.TABLE1 : : : ------- FILE1 : CREATE TABLE TEMP.TABLE2 : : : ------- FILE2 : CREATE TABLE TEMP.TABLE2 : : : -------
Re: between pattern search not working\e^DiOnline perltidy
by Anonymous Monk on Jan 15, 2015 at 12:27 UTC

    Anybody know of online version of perltidy?