Reputation: 574
I have some "kind of SQL" files that I want to be partially sorted - to be able to compare them with each other later on.
CREATE TABLE BBBBBB
(
ID bigint NOT NULL
NAME varchar(50)
CURRENCY varchar(3)
SYS_START timestamp NOT NULL
SYS_END timestamp NOT NULL
TS_ID timestamp NOT NULL
EXPORT int
)
CREATE TABLE AA
(
ID bigint NOT NULL
SYS_START timestamp NOT NULL
SYS_END timestamp NOT NULL
TS_ID timestamp NOT NULL
NAME varchar(100) NOT NULL
)
I only want to have the parts inside the brackets sorted. The output shall be this:
CREATE TABLE BBBBBB
(
CURRENCY varchar(3)
EXPORT int
ID bigint NOT NULL
NAME varchar(50)
SYS_END timestamp NOT NULL
SYS_START timestamp NOT NULL
TS_ID timestamp NOT NULL
)
CREATE TABLE AA
(
ID bigint NOT NULL
NAME varchar(100) NOT NULL
SYS_END timestamp NOT NULL
SYS_START timestamp NOT NULL
TS_ID timestamp NOT NULL
)
I tried to put the parts in brackets into the sed hold buffer and sort them, but I didn't get far ... I don't have other ideas right now.
Upvotes: 2
Views: 447
Reputation: 14955
Or gawk
:
gawk 'BEGIN{PROCINFO["sorted_in"] = "@ind_str_asc"}
/^\(/{f=1}
/^\)/{f=0
for (i in a)
print a[i]
delete a}
f{a[$1]=$0}
!f' yourfile
Check the ideone demo here.
From the docs
"@ind_str_asc" Order by indices in ascending order compared as strings; this is the most basic sort. (Internally, array indices are always strings, so with ‘a[2*5] = 1’ the index is "10" rather than numeric 10.)
Upvotes: 2
Reputation: 134
A solution using Vim:
vim -c ":/^(/+1,/^)/sort | /^(/-1 | /^(/+1,/^)/sort | wq" x.txt
Upvotes: 2
Reputation: 5298
With awk
:
awk 'i {a[l++]=$0}
/^\(/ {print; i=1}
/^\)/ {n=asort(a); for(k=1; k<=n; k++){print a[k]} i=0; delete a; next}
!i' File
Upvotes: 2
Reputation: 241898
Perl to the rescue!
perl -ne '
$between = /^\(/ .. /^\)/;
push @buff, $_ if $between && /^\s/;
print "(\n", sort splice(@buff), ")\n" if $between =~ /E/;
print unless $between
' -- file.sql
-n
reads the input line by line(
and )
at the beginning of a line.Upvotes: 1