0

I've got a file.sql file from an informix database export. The following is a small part of the file (I changed the data a little bit to make it anonymous):

grant dba to "xxx";
grant dba to "yyy";
grant dba to "zzz";

{ TABLE "xxx".table1 row size = 66 number of columns = 5 index size = 54 }
{ unload file name = table00100.unl number of rows = 307 }

create table "xxx".table1 
  (
    field1 char(2) not null ,
    field2 char(10) not null ,
    field3 char(30),
    field4 char(20) not null ,
    field5 date not null 
  );
revoke all on "xxx".table1 from "yyy";

What I need from this file is to name the table00100.unl file back to the original table name. So I need an output like this:

mv table00100.unl table1

I've managed to to this with 2 files in between with a little of awk and sed, but isn't this possible in an easier way without the temporary files in between? My code sample:

awk '{for(i=1;i<=NF;i++) {if ($i=="unload") {print $(i+4)} else {if ($i=="TABLE") print $(i+1)}}}' file.sql | sed 's/".*".//' > temp.out
awk 'NR%2{printf "%s ",$0;next;}1' temp.out | awk '{for (i=NF;i>0;i--) if (i > 1) printf("mv %s ",$i); else printf("%s\n",$i)}' > temp.shl

4 Answers 4

4

if you want to use awk solely:

/TABLE/ {
    sub("\".+\"\\.", "", $3);
    table = $3;
}
/unload/ {
    print "mv", $6, table;
};
Sign up to request clarification or add additional context in comments.

4 Comments

Can I change the print "mv", $6, table; to system("mv " $6 " " table); to execute the move immediately?
of course, you could, but IMHO, you'd better output those scripts to console or a file to examine its correctness first.
The first arg for sub() is a regexp not a string so use regexp delimiters so awk doesn't have to parse it twice, i.e. sub(/".+"\./, "", $3). Also the move should provide quotes, printf "mv \047%s\047 \047%s\047\n", $6, table so when the shell executes it later it's not exposed for globbing, word splitting and filename expansion. Finally - you don't need the trailing semicolons on each line.
@nightfox79 you really shouldn't have awk involved in printing mv or executing mv at all as that's creating tight coupling between the awk script and the calling shell script. Just have awk find and print the from and to names and then let the calling shell shell do the mv or whatever else with them.
1

Similar to georgexsh's solution, but with gensub:

awk '/TABLE/{table=gensub(/.*\./, "", "", $3)}/unload/{print "mv", $6, table }'

Comments

0
awk '($0 ~ /{ *TABLE/)  { match($0,/TABLE */); to=substr($0,RSTART+RLENGTH);
                          match(to," ");       to=substr(to,1,RSTART-1);
                          match(to,"[.]");     to=substr(to,RSTART+1);
                        }
     ($0 ~ /{ *unload/) { match($0,"name *= *"); from=substr($0,RSTART+RLENGTH); 
                          match(from," ");       from=substr(from,1,RSTART-1)
                        }
     (from!="") && (to!="") { exit }
     END {print "mv "from" "to}' file

The reason I make it so "complicated" is that I am not sure about all the spacings in your input if they will be consistent and if the ordering in the braces will always be the same.

1 Comment

This gives only the first table, I have over 300 lines like that, how can I loop this
0

Using a perl one line ( of course it is long :-))

> cat informix_unload.txt
grant dba to "xxx";
grant dba to "yyy";
grant dba to "zzz";

{ TABLE "xxx".table1 row size = 66 number of columns = 5 index size = 54 }
{ unload file name = table00100.unl number of rows = 307 }

create table "xxx".table1
  (
    field1 char(2) not null ,
    field2 char(10) not null ,
    field3 char(30),
    field4 char(20) not null ,
    field5 date not null
  );
revoke all on "xxx".table1 from "yyy";

grant dba to "xxx";
grant dba to "yyy";
grant dba to "zzz";

{ TABLE "xxx".table2 row size = 66 number of columns = 5 index size = 54 }
{ unload file name = table00200.unl number of rows = 307 }

create table "xxx".table2
  (
    field1 char(2) not null ,
    field2 char(10) not null ,
    field3 char(30),
    field4 char(20) not null ,
    field5 date not null
  );
revoke all on "xxx".table1 from "yyy";
-- other data

> perl -ne 'BEGIN{$x=qx(cat informix_unload.txt);while($x=~m/(.+?)unload file name = (\S+)(.+?)create table (\S+)(.+)/osm){$x=$5;print "$2 $4\n";}exit}'
table00100.unl "xxx".table1
table00200.unl "xxx".table2
>

check this out

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.