Shell 如何删除除包含TRUNCATE-INSERT(包括包名)的行以外的所有行

Shell 如何删除除包含TRUNCATE-INSERT(包括包名)的行以外的所有行,shell,awk,ksh,Shell,Awk,Ksh,这是对这个问题的延伸: 我之前问过这个问题,因为我需要一些帮助从生成的脚本中删除行,anubhava的一些伟大帮助中的thanx我能够解决这个问题,但现在的问题是我被要求在生成的脚本中包含包名,因此: PROCEDURE VALIDA_CAMBIO_GPR TRUNCATE TMP_MOD_PVA INSERT TMP_MOD_PVA PROCEDURE AJUSTAR_FECHAS INSERT PRO_TDA_VARLOG_ALM PROCEDURE DEPURAR_CAMBIOS_GPR

这是对这个问题的延伸:

我之前问过这个问题,因为我需要一些帮助从生成的脚本中删除行,anubhava的一些伟大帮助中的thanx我能够解决这个问题,但现在的问题是我被要求在生成的脚本中包含包名,因此:

PROCEDURE VALIDA_CAMBIO_GPR
TRUNCATE TMP_MOD_PVA
INSERT TMP_MOD_PVA
PROCEDURE AJUSTAR_FECHAS
INSERT PRO_TDA_VARLOG_ALM
PROCEDURE DEPURAR_CAMBIOS_GPR
PROCEDURE INC_EX_0001
INSERT CABECERA_ALARMAS
PROCEDURE INC_EX_0002
INSERT CABECERA_ALARMAS
PROCEDURE INC_EX_0003
INSERT CABECERA_ALARMAS
PROCEDURE INC_EX_0005
INSERT CABECERA_ALARMAS
PROCEDURE INC_EX_0007
INSERT CABECERA_ALARMAS
PROCEDURE INC_EX_0008
INSERT CABECERA_ALARMAS
PROCEDURE INC_EX_0009
INSERT CABECERA_ALARMAS
PROCEDURE INC_EX_0010
INSERT CABECERA_ALARMAS
PROCEDURE INC_EX_0011
INSERT CABECERA_ALARMAS
这是我最初的问题,我有一个长文本文件,其中有这样的行,但我想删除所有没有每个过程两个INSERT-TRUNCATE的行,因此前一行的结果将是

PROCEDURE VALIDA_CAMBIO_GPR
TRUNCATE TMP_MOD_PVA
INSERT TMP_MOD_PVA
为此,我们使用了这个AWK

 awk '$1=="PROCEDURE"{p=$0;next} p && $1=="TRUNCATE"{t=$2;next} t==$2 && $1=="INSERT"{print p; print "TRUNCATE " t; print "INSERT " t; print ""; t=""}'
好的,到目前为止我没有问题,但是现在,当我被告知在过程中包含包名时,我的文本文件如下所示

PACK PACKENVI
PROCEDURE VALIDA_CAMBIO_GPR
TRUNCATE TMP_MOD_PVA
INSERT TMP_MOD_PVA
PACKANSI
PROCEDURE CALCULA_GRAMOS
PACK PACKBRUM
PROCEDURE AJUSTAR_FECHAS
INSERT PRO_TDA_VARLOG_ALM
PACK PACKRENSI
PROCEDURE DEPURAR_CAMBIOS_GPR
PACK PACKRENSI
PROCEDURE INC_EX_0001
INSERT CABECERA_ALARMAS
PACK PACKRENSI
PROCEDURE INC_EX_0002
INSERT CABECERA_ALARMAS
PACK PACKRENSI
PROCEDURE INC_EX_0003
INSERT CABECERA_ALARMAS
PACK PACKRENSI
PROCEDURE INC_EX_0005
INSERT CABECERA_ALARMAS
PACK PACKRENSI
PROCEDURE INC_EX_0007
INSERT CABECERA_ALARMAS
PACK PACKRENSI
PROCEDURE INC_EX_0008
INSERT CABECERA_ALARMAS
PACK PACKRENSI
PROCEDURE INC_EX_0009
INSERT CABECERA_ALARMAS
PACK PACKRENSI
PROCEDURE INC_EX_0010
INSERT CABECERA_ALARMAS
PACK PACKRENSI
PROCEDURE INC_EX_0011
INSERT CABECERA_ALARMAS
本文的预期输出为:

PACK PACKENVI
PROCEDURE VALIDA_CAMBIO_GPR
TRUNCATE TMP_MOD_PVA
INSERT TMP_MOD_PVA
这与以前的问题几乎相同,只是当在包下面的一个过程下面发现一对INSERT-TRUNCATE时,需要打印另一行,如果一个过程是多对INSERT\U TRUNCATE,则必须打印所有对

非常感谢,如果您在理解上有困难,请查看原始问题

Awk解决方案

awk '/PACK/{P=$0}/PROCEDURE/{p=$0}/TRUNCATE/{t=$0}t~$2&&/INSERT/{print P RS p RS t RS $0;P=p=t=0}' file

PACK PACKENVI
PROCEDURE VALIDA_CAMBIO_GPR
TRUNCATE TMP_MOD_PVA
INSERT TMP_MOD_PVA

对于需要打印的所有其他行,只需添加另一个
/LINE/{?=$0}
,并将其添加到打印部分(其中
是一个变量)

我发现解决方案只是修改原始AWK,这里是新的一个

awk '$1=="PACK"{s=$0;next} s && $1=="PROCEDURE"{p=$0;next} p && $1=="TRUNCATE"{t=$2;next}
t==$2 && $1=="INSERT"{print s; print p; print "TRUNCATE " t; print "INSERT " t; print ""; t=""}'

我希望在找到每一双后都有一条空行。谢谢你的帮助,但我已经根据我原来的AWK制定了自己的解决方案。我在回答中没有添加到你原来的AWK中的原因是有相当多的部分是多余的。不需要
next
s,而是检查
s
p
是否存在。此外,可能不需要与
$1
进行比较,除非您预期值也为$2。最后,您可以使用RS作为每个变量之间的换行符,而不是重复打印。感谢您提供的非常有用的注释,请查看我的awk代码,我对awk非常陌生,很难习惯。谢谢,我会投票支持你的答案,因为它完全符合我的要求!;)