user1797693
user1797693

Reputation:

Need to fetch the lines in front of a string

I have a file source.txt like the following:

Executing resource: L:\Core\SQL\smpks_fcj_csdovdmt_addon.sql  
Failed to execute: 
Executing resource: L:\LC\SQL\lcpks_lcdtronl_utils.sql  
Executing resource: L:\LS\SQL\cspks_adhoc_charge_sch.sql  
Failed to execute:   
SHO ERR  
Executing resource: L:\LS\SQL\gwpks_ls_adhocsch_operations.sql  
Executing resource: L:\LS\SQL\lnpks_synd_services.sql  
Failed to execute:  
Executing resource: L:\LS\SQL\lspks_facility_contracts.sql  
Executing resource: L:\LS\SQL\lspks_fcj_lsdpxlog.sql  
Executing resource: L:\LS\SQL\lspks_lsdprmnt_kernel.sql  
Failed to execute:  
sho err;

From this file I need to get the lines just in front of the sting "Failed to execute:" and put it into a new file result.txt. One more condition, if "Failed to execute:" is followed by "sho err: or "SHO ERR" I dont need that file in the result. The output of the above mentioned file should be:

Executing resource: L:\Core\SQL\smpks_fcj_csdovdmt_addon.sql  
Executing resource: L:\LS\SQL\lnpks_synd_services.sql

Please help. Perl script or batch file or Ant script is fine.

If I get an option like, if "Sho err" is there, delete the previous line, its fine.

Upvotes: 0

Views: 94

Answers (4)

dbenham
dbenham

Reputation: 130819

Extending my native batch solution found at Need to copy the lines just before a particular string using batch file:

First use FINDSTR to remove any Failed to execute: that is followed by SHO ERR and pipe results to another FINDSTR that saves remaining lines that are followed by Failed to execute:

@echo off
setlocal
::Define LF variable containing a linefeed (0x0A)
set LF=^


::Above 2 blank lines are critical - do not remove

::Define CR variable containing a carriage return (0x0D)
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"

setlocal enableDelayedExpansion
::regex "!CR!*!LF!" will match both Unix and Windows style End-Of-Line
findstr /vbric:"Failed to execute:.*!CR!*!LF!SHO ERR" "test.txt" ^
 | findstr /ric:"!CR!*!LF!Failed to execute:" >failed.txt

type failed.txt

Upvotes: 2

Guru
Guru

Reputation: 16974

Using tac and sed:

$ tac file | sed -n  -e '/sho err\|SHO ERR/{N;d;}' -e '/Failed to execute/{n;p;}' | tac
Executing resource: L:\Core\SQL\smpks_fcj_csdovdmt_addon.sql
Executing resource: L:\LS\SQL\lnpks_synd_services.sql

Upvotes: 1

amon
amon

Reputation: 57600

Just another Perl solution:

#!/usr/bin/perl

use 5.012; use warnings;

my $last = "";
my $commit_ready = 0;

while (<>) {
  if (/^Failed to execute:/) {
    $commit_ready = 1;
  } else {
    print $last if $commit_ready and not /^sho err/i;
    $commit_ready = 0;
    $last = /^Executing resource: (.*)/ ? $1 : "";
  }
}
print $last if $commit_ready;

Usage is the same as with the @sergio script.

Upvotes: 1

sergio
sergio

Reputation: 69027

This works for me:

grep -B 1 "Failed" sources.txt  | grep "Executing resource:" > results.txt

EDIT: to take into account he "SHO ERR" requirement, possibly it is better to use Perl:

my @lines = <>;
push @lines, "";
push @lines, "";
my $linesNum = @lines;
for ( $i = 0; $i < $linesNum - 2; $i++) {
   if ($lines[$i+1] =~ /Failed to execute:/) {
     if (!($lines[$i+2] =~ /SHO ERR/i)) {
        print $lines[$i] if $lines[$i] =~ /^Executing/
     }
   }
 }

you can use it like this:

cat sources.txt | perl script.pl > results.pl

or

perl script.pl sources.txt > results.pl

Upvotes: 2

Related Questions