How to delete all lines except lines that include

2019-09-07 11:41发布

问题:

this is an extension to this question: How to delete all lines except lines that include TRUNCATE - INSERT

I had earlier asked that question because i needed some help deleting line from a generated script, thanx from some great help from anubhava i was able to solve the problem, but now the proble is that i have been asked to include the pack name into my generated script, so:

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

This was my original problem where i had a long text file with lines like that, but i wanted to delete all lines that did not have a couple of INSERT-TRUNCATE per procedure, so the result from the previous line would be

PROCEDURE VALIDA_CAMBIO_GPR
TRUNCATE TMP_MOD_PVA
INSERT TMP_MOD_PVA

To do this we used this 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=""}'

Ok, so up to here i have no problem, but now, when i have been told to include the PACK name obove the procedure, my text file looks like this.

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

The desired output from this text would be:

PACK PACKENVI
PROCEDURE VALIDA_CAMBIO_GPR
TRUNCATE TMP_MOD_PVA
INSERT TMP_MOD_PVA

It is pretty much the same problem as before, only that there is another line that needs to be printed when a couple of INSERT-TRUNCATE is found below a procedure below a PACK, if a procedure as more than one couple of INSERT_TRUNCATE, all pairs must be printed.

Thanks a lot, if you had trouble understanding take a look at the original question.

回答1:

Awk solution

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

For all further lines that need to be printed just add another /LINE/{?=$0} and add it to the print part as well(where ? is a variable)



回答2:

I found the solution just modifying the original AWK, here is the new one

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=""}'


标签: shell awk ksh