我有一个文件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;
从这个文件中,我需要在sting“执行失败:”之前获取行,并将其放入新文件result.txt中。还有一个条件,如果“执行失败:”之后是“笑错误:或”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”在那里,删除上一行,罚款。
答案 0 :(得分: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
答案 1 :(得分:2)
扩展我在Need to copy the lines just before a particular string using batch file找到的原生批量解决方案:
首先使用FINDSTR删除Failed to execute:
后跟的所有SHO ERR
,并将结果传输到另一个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
答案 2 :(得分: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脚本相同。
答案 3 :(得分: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