extracting block of lines from a file

consider the input file which i am dealing with looks like this..

#cat 11.sql
 
create table abc (
.
.
.
) engine=Innodb ;
.
.
etc
.
.
.
create table UsM (
 blah
blah
blah
) engine=Innodb ;
.
.
.
drop procedure if exists b77 ;
Delimiter $$
CREATE PROCEDURE b77(id int)
BEGIN
END
$$
Delimiter ;
.
.
.
drop procedure if exists a77;
Delimiter $$
CREATE PROCEDURE a77(id int)
BEGIN
END
$$
Delimiter ;
.
.
CREATE PROCEDURE gNodes (LEVEL INT)
BEGIN
 blah
blah
.
.
        SET rootName = (SELECT DirectoryCategory.name FROM DirectoryCategory WHERE DirectoryCategory.id IN (SELECT DirectoryTree.directoryCategoryId FROM DirectoryTree WHERE DirectoryTree.id=rootId)) ;
    
        DROP TABLE IF EXISTS ResultNodes ;
        CREATE TABLE ResultNodes (id INT, NAME TEXT) ;
  END IF ;
  
  IF LEVEL>0 THEN
        SET parentPrefix = CONCAT(pa etc etc
.
.
END
$$
Delimiter ;

here somewhere in the middle of a procedure there is a "create table" thing... i am perfroming some action so that all create table to Engine=innodb is exctarcted to a file.. that command used is as below

perl -lne '(/^\s*create\s+table/i .. /^\s*\)\s+engine=Innodb/i) && print;' "11.sql" > onlytables.sql

but the problem is since there is a create table line in between a procedure even it is considered as a table and extracted... how to avoid this... i could perfrom this action in a while loop where it extractes all tables to a file and break when it encounters any line with create procedure in it( since create table lines come in first part of file and procedures comes next) but i need one liners to perfrom this action... any help is deeply appreciated .... :wall::wall:

reverse logic:

perl -e 'print reverse <>' "11.sql"|perl -lne '(/\s+engine=Innodb/i .. /create\s+table/i) && print;'|perl -e 'print reverse <>'
1 Like

Can you remove the case-insensitive character and try, if that does not matter really..?

# awk variant..
awk '/create table|engine/{++i}i{x=x"\n"$0}i==2{print x;x=i=""}' inputfile
1 Like

thanks guys.... both the commands (of @Klashxx and of @michaelrozar17) worked... you guys saved my life.. :-)... thanks a lot :slight_smile:

In one perl call:

perl -e '@a=reverse <>;foreach (@a){push (@b,$_) if /\s+engine=Innodb/i .. /create\s+table/i};print reverse(@b),"\n"' "11.sql"
1 Like

thanks even this is working :slight_smile: