0

我有一个文件 source.txt,如下所示:

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;

从这个文件中,我需要获取“执行失败:”字符串前面的行,并将其放入新文件 result.txt。还有一个条件,如果“执行失败:”后跟“sho err:”或“SHO ERR”,我不需要该文件在结果中。上述文件的输出应该是:

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

请帮忙。Perl 脚本或批处理文件或 Ant 脚本都可以。

如果我得到一个选项,如果“Sho err”在那里,删除前一行,没关系。

4

4 回答 4

2

这对我有用:

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

编辑:考虑到他的“SHO ERR”要求,使用 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/
     }
   }
 }

你可以像这样使用它:

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

或者

perl script.pl sources.txt > results.pl
于 2012-11-09T09:08:44.797 回答
2

扩展我在需要使用批处理文件复制特定字符串之前的行中找到的本机批处理解决方案:

首先使用 FINDSTR 删除Failed to execute:后面的任何内容,SHO ERR并将结果通过管道传输到另一个 FINDSTR,该 FINDSTR 保存后面的剩余行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
于 2012-11-09T12:48:45.103 回答
1

只是另一个 Perl 解决方案:

#!/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;

用法与@sergio 脚本相同。

于 2012-11-09T09:52:53.953 回答
1

使用 tac 和 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
于 2012-11-09T10:12:05.713 回答