2

Please help me to delete particular block in a file.

input is like ,

<section_begin> a01 
dfasd
adfa
<section_end>
<section_begin> a02
..
eld
...
1 error reported
...
<section_end>
<section_begin> a03 
qwre
adfa
<section_end>

I want to remove the particular block

<section_begin> a02
..
search_string
...
<section_end>

the below command returns first section also.

perl -ne 'print if /<section_begin>/../eld/' a1exp

3 Answers 3

4

You can still use the flip-flop operator, but reverse it and match the start and end of section 2:

perl -ne 'print unless /^<section_begin> a02$/ .. /^<section_end>$/' a1exp

unless means if not, so it will not print whenever the expression matches. The flip-flop itself will return false as long as the LHS (left hand side) returns false, and then return true until the RHS returns true, after which it is reset. Read more on that in the documentation.

This can also be used when checking if a section contains a keyword by caching the section before printing.

perl -ne 'if (/^<section_begin>/ .. /^<section_end>/) { $sec .= $_ }; 
          if (/^<section_end>/) { print $sec if $sec !~ /eld/; $sec = "" }' 
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your help . actually I'm searching eld ... value.more than one sections present in a file. so I can't use a02 directly. Please help me.
I'm sorry, I can't help if I don't know what you want to do. You say not skip a02, but you don't say what you want.
the file contains - <section_begin> a01 dfasd adfa <section_end> <section_begin> a02 .. eld ... 1 error reported ... <section_end> <section_begin> a03 qwre adfa <section_end> <section_begin> a04 .. eld ... <section_end> <section_begin> a05 qwre adfa <section_end> <section_begin> a06 .. eld ... <section_end> wherever eld is mentioned, I want to omit those sections. wants to disply only a01,a03,a05 sections output should be- <section_begin> a01 dfasd adfa <section_end> <section_begin> a03 qwre adfa <section_end> <section_begin> a05 qwre adfa <section_end>
So basically you need to check the entire section for a keyword, and if it is there, don't print the section. The solution would then be to store each section in a variable, check if it contains the keyword, and then print. I'll update with the algorithm, but you'll have to tweak it to your data.
2

You could try to use something like that:

#!/usr/bin/perl

use strict;
use warnings;

my $bool = 0;
while (my $line = <DATA>) {
  if ($line =~ /section_end/) {
    my $temp_bool = $bool;
    $bool = 0;
    next if $temp_bool;
  }
  $bool = 1 if ($line =~ /section_begin/ && $line =~ /a02/ );
  next if $bool;
  print $line;
}




__DATA__

<section_begin> a01 
dfasd
adfa
<section_end>
<section_begin> a02
..
eld
...
1 error reported
...
<section_end>
<section_begin> a03 
qwre
adfa
<section_end>

I set here a bool variable to control the part which should be skipped. To make sure, that the end part of the skipped block will be skipped as well, i use a temp_bool variable.

Comments

2

The straight forward solution might be the best in this case:

perl -ne '/<section_begin> (.+)/;print if $1 ne "a02"' a1exp

$1 will be updated every time the regex sees a new section and then you just print everything not in the "a02" section.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.