Perl: Conditional replace based on previous and current value in a line


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Perl: Conditional replace based on previous and current value in a line
# 1  
Old 02-27-2012
Perl: Conditional replace based on previous and current value in a line

I need to read the contents of a file. Then I need to grep for a keyword and replace part of the grepped line based on the condition of previous and present line.


Example input file:
Code:
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0; /* if next shift_port is P0 I need to replace this with M0; and next shift_port's P0; with 00;
    port3       = 0;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;
    port3       = 0;
    reset       = 1;
   }
  Macro "Inputs" { 
    test_ip =
        110111010110
  }

  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00;
    port3       = 0;
    reset       = 1;
  }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00; 
    port3       = 0;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;/* if next shift_port is P0; I need to replace this with M0; and next shift_port's P0 with 00;
    port3       = 0;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;/* if next shift_port is P0; I need to replace this with M0; and next shift_port's P0 with 00;
    port3       = 0;
    reset       = 1;
   }
}

Desired output file
Code:
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = M0; /* if next shift_port is P0; I need to replace this with M0; and next shift_port's P0 with 00;
    port3       = 0;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00;
    port3       = 0;
    reset       = 1;
   }
  Macro "Inputs" { 
    test_ip =
        110111010110
  }

  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00;
    port3       = 0;
    reset       = 1;
  }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00; 
    port3       = 0;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = M0;/* if next shift_port is P0; I need to replace this with M0; and next shift_port's P0 with 00;
    port3       = 0;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00;/* if next shift_port is P0; I need to replace this with M0; and next shift_port's P0 with 00;
    port3       = 0;
    reset       = 1;
   }
}

I am trying to use a perl script to implement this.

Thanks in advance for your help

---------- Post updated at 08:03 AM ---------- Previous update was at 07:59 AM ----------

I am able to display the line that have 2 P0; with the following piece of code. But I need to write the output to a separate file


Code:
#!/tool/pandora/bin/perl5.10.0 
use strict;
my $count = 0;
open(INFILE, "<$ARGV[0]");
my @data_in_file = <INFILE>;
close (INFILE);
my @shifts = grep { /shift_port = / } @data_in_file;
foreach my $line (@shifts) 
{
	if ($line=~m/shift_port = P0;/) 
	{
		  $count++;
		 print "$count\n";	
		if ($count == 2)
			{
			print "found 2 P0\n";
			$count = 0;
			}
	} else {
		$count = 0;
	}

}

# 2  
Old 02-27-2012
Hi naveen@,

I don't understand your perl script. It outputs nothing with that input file, and I think you didin't match the exact withespace.

Try next one:
Code:
$ cat infile
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0; /* if next shift_port is P0 I need to replace this with M0; and next shift_port's P0; with 00;
    port3       = 0;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;
    port3       = 0;
    reset       = 1;
   }
  Macro "Inputs" { 
    test_ip =
        110111010110
  }

  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00;
    port3       = 0;
    reset       = 1;
  }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00; 
    port3       = 0;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;/* if next shift_port is P0; I need to replace this with M0; and next shift_port's P0 with 00;
    port3       = 0;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;/* if next shift_port is P0; I need to replace this with M0; and next shift_port's P0 with 00;
    port3       = 0;
    reset       = 1;
   }
}
$ cat script.pl
use warnings;
use strict;

die qq[Usage: perl $0 <input-file>\n] unless @ARGV == 1;

my @range_lines = ();

while ( <> ) {
        chomp;
        if ( m/\A\s*(?i:shift_port)\s*=/ ... m/\A\s*(?i:shift_port)\s*=/ ) {
                push @range_lines, $_;
                next;
        }

        if ( @range_lines ) {
                if ( $range_lines[0] =~ m/=\s*P0\s*;/ &&
                         $range_lines[ $#range_lines ] =~ m//
                ) {
                        $range_lines[0] =~ s/P0/M0/;
                        $range_lines[ $#range_lines ] =~ s/P0/00/;
                }

                printf qq[%s\n], join qq[\n], splice @range_lines;
        }

        printf qq[%s\n], $_;
}
$ perl script.pl infile
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = M0; /* if next shift_port is P0 I need to replace this with M0; and next shift_port's P0; with 00;
    port3       = 0;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00;
    port3       = 0;
    reset       = 1;
   }
  Macro "Inputs" { 
    test_ip =
        110111010110
  }

  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00;
    port3       = 0;
    reset       = 1;
  }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00; 
    port3       = 0;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = M0;/* if next shift_port is P0; I need to replace this with M0; and next shift_port's P0 with 00;
    port3       = 0;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00;/* if next shift_port is P0; I need to replace this with M0; and next shift_port's P0 with 00;
    port3       = 0;
    reset       = 1;
   }
}

Regards,
Birei
This User Gave Thanks to birei For This Post:
# 3  
Old 02-27-2012
Hi Birei,

I need another small improvement in the code

Say the input file is the one below. I need to replace 1st P0 with M0 and second with 00 if and only if the value of port3 is not 1 on both V{}

Input file

Code:
V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0; 
    port3       = 1; /* port 3 is 1 . So dont replace this even if next shift port is P0 */
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0; /* port 3 is 0 and current shift_port is P0. If port 3 is 0 in next v{} and shift_port is P0 then replace this with M0 and next shift port with 00 */
    port3       = 0;
    reset       = 1;
   }

 W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;
    port3       = 0;
    reset       = 1;
   }

  Macro "Inputs" { 
    test_ip =
        110111010110
  }

  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;
    port3       = 1; /* port 3 is 1 . So dont replace this even if next shift port is P0 */
    reset       = 1;
  }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00; 
    port3       = 1;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;
    port3       = 1;  /* port 3 is 1 . So dont replace this even if next shift port is P0 */
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0; /* port 3 is 0 and current shift_port is P0. If port 3 is 0 in next v{} and shift_port is P0 then replace this with M0 and next shift port with 00 */
    port3       = 0;
    reset       = 1;
   }
 W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0; 
    port3       = 0;
    reset       = 1;
   }
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;
    port3       = 1;  /* port 3 is 1 . So dont replace this even if next shift port is P0 */
    reset       = 1;
   }
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;
    port3       = 1;  /* port 3 is 1 . So dont replace this even if next shift port is P0 */
    reset       = 1;
   }
}

Required output

Code:
V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0; 
    port3       = 1; /* port 3 is 1 . So dont replace this even if next shift port is P0 */
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = M0; /* port 3 is 0 and current shift_port is P0. If port 3 is 0 in next v{} and shift_port is P0 then replace this with M0 and next shift port with 00 */
    port3       = 0;
    reset       = 1;
   }

 W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00;
    port3       = 0;
    reset       = 1;
   }

  Macro "Inputs" { 
    test_ip =
        110111010110
  }

  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;
    port3       = 1; /* port 3 is 1 . So dont replace this even if next shift port is P0 */
    reset       = 1;
  }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00; 
    port3       = 1;
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;
    port3       = 1;  /* port 3 is 1 . So dont replace this even if next shift port is P0 */
    reset       = 1;
   }
  W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = M0; /* port 3 is 0 and current shift_port is P0. If port 3 is 0 in next v{} and shift_port is P0 then replace this with M0 and next shift port with 00 */
    port3       = 0;
    reset       = 1;
   }
 W wf_cyc;
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = 00; 
    port3       = 0;
    reset       = 1;
   }
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;
    port3       = 1;  /* port 3 is 1 . So dont replace this even if next shift port is P0 */
    reset       = 1;
   }
  V { 
    port1       = P;
    port2       = 0;
    shift_port  = P0;
    port3       = 1;  /* port 3 is 1 . So dont replace this even if next shift port is P0 */
    reset       = 1;
   }
}


Last edited by naveen@; 02-28-2012 at 11:48 AM.. Reason: clear explanation
# 4  
Old 02-28-2012
Why didn't you post that input file in your first message? And why didn't you tell us all your requirements at once? Because probably that doesn't involve an improvement in the code, but to redo it with other approach. Take it as an advice, but you will find more help if work like that.

Quote:
Say the input file is the one below. I need to replace 1st P0 with M0 and second with 00 if and only if the value of port is 1 on both V{}
What does it mean? I don't see any 'port' value in your input file.
# 5  
Old 02-28-2012
Sorry about the lack of clarity and also not specifying the requirements upfront. I edited the improvement requested above to make it clear.
Thanks in advance for your help
# 6  
Old 02-28-2012
Why do you have two threads about the same topic? crossposting is against the rules.
# 7  
Old 02-28-2012
I wanted a perl and shell script. So you were helping me with awk and Birei was with perl. So i didnt delete the duplicate post. Initially I didnt know which category I should have posted. sorry about that
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

sed conditional \n replace for each line

How could be removed \n only if appearing at position 80 in the line? (4 Replies)
Discussion started by: RomanF
4 Replies

2. Shell Programming and Scripting

Replace first field of a line with previous filed of the line

Hi Everyone, I have a file as below: IM2345638,sherfvf,usha,30 IM384940374,deiufbd,usha,30 IM323763822,cdejdkdnbds,theju,15 0,dhejdncbfd,us,20 IM398202038,dhekjdkdld,tj,30 0,foifsjd,u2,40 The output i need is as below IM2345638,sherfvf,usha,30... (4 Replies)
Discussion started by: usha rao
4 Replies

3. Shell Programming and Scripting

Perl to send previous and current value

For example, I have a file called number.txt. x y 1 1 2 4 3 9 4 6 5 5 6 6 7 9 8 4 9 1 10 0 ... And I want to print out the value of x and y, if y%4==0 and the next value of y%4==0. Thus, the sample output is: 1 1 *because the previous x before 2 is 1 2 4 *because 4%4 == 0 7 9... (2 Replies)
Discussion started by: Tzeronone
2 Replies

4. Shell Programming and Scripting

Sed Comparing Parenthesized Values In Previous Line To Current Line

I am trying to delete lines in archived Apache httpd logs Each line has the pattern: <ip-address> - - <date-time> <document-request-URL> <http-response> <size-of-req'd-doc> <referring-document-URL> This pattern is shown in the example of 6 lines from the log in the code box below. These 6... (1 Reply)
Discussion started by: Proteomist
1 Replies

5. UNIX for Dummies Questions & Answers

Awk to print data from current and previous line

Hi guys, I have found your forum super useful. However, right now I am stuck on a seemingly "simple" thing in AWK. I have two columns of data, the first column in Age (in million years) and the second column is Convergence Rate (in mm/yr). I am trying to process my data so I can use it to... (2 Replies)
Discussion started by: awk_noob_456
2 Replies

6. Shell Programming and Scripting

Printing previous line based on pattern using sed

Hi, I have a written a shell script to get the previous line based on the pattern. For example if a file has below lines: ---------------------------------------------- #UNBLOCK_As _per #As per 205.162.42.92 #BLOCK_As_per #----------------------- #input checks abc.com... (5 Replies)
Discussion started by: Anjan1
5 Replies

7. Shell Programming and Scripting

How to use sed to search for string and Print previous two lines and current line

Hello, Can anybody help me to correct my sed syntax to find the string and print previous two lines and current line and next one line. i am using string as "testing" netstat -v | sed -n -e '/test/{x;2!p;g;$!N;p;D;}' -e h i am able to get the previous line current line next line but... (1 Reply)
Discussion started by: nmadhuhb
1 Replies

8. Shell Programming and Scripting

Print previous, current and next line using sed

Hi, how can i print the previous, current and next line using sed? current line is the matching line. The following prints all lines containing 'Failure' and also the immediate next line cat $file | sed -n -e '/Failure/{N;p;}' Now, i also want to print the previous line too. Thanks,... (8 Replies)
Discussion started by: ysrinu
8 Replies

9. Shell Programming and Scripting

sed conditional string replace for each line

Hi all, I appreciate the enormous amount of knowledge that flows in this forum. I am an average UNIX user. I have many files with lines like the below. I have separated each line with space for ease of reading. I need to replace the first occurance of "/00" with null on those lines that have... (6 Replies)
Discussion started by: Nanu_Manju
6 Replies

10. Shell Programming and Scripting

replace [previous] line

Hi ,suppose I have a file title=dsafsadf ........ ....... year=1995 author=john smith ............ title=bbbbbb ........ ....... year=1988 author=alex I need to replace the title line with a expression that contains variables year and author. I want to use a python readline for loop.... (10 Replies)
Discussion started by: grossgermany
10 Replies
Login or Register to Ask a Question