I have a problem with mysqldump that might be solved by configuring mysqldump differently, but probably will be solved by just piping the output through a shell script.
Basically, mysqldump
always outputs the tables in the same order, but it list all columns (other than id
) for each table in random order.
So, the first run might output this…
create TABLE `ONE` (
`id` int NOT NULL AUTO_INCREMENT,
`column_a` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`column_b` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`column_c` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
create TABLE `TWO` (
`id` int NOT NULL AUTO_INCREMENT,
`column_x` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`column_y` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`column_z` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
…and on the second run, it might produce something like this:
create TABLE `ONE` (
`id` int NOT NULL AUTO_INCREMENT,
`column_c` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`column_b` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`column_a` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
create TABLE `TWO` (
`id` int NOT NULL AUTO_INCREMENT,
`column_y` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`column_x` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`column_z` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
I’d like to pipe the result through a shellscript that always sorts the lines in the same way. What script would achieve this? The script needs to run on a build agent that runs on Ubuntu, so if it is possible and practical to use standard GNU tools like awk
then that would be superior to using custom tools.
2
Answers
I would harness GNU
AWK
for this task following way, letfile.txt
content bethen
gives output
Explanation: I inform GNU
AWK
that Scanning Order should be values-as-strings, ascending and set toindent
to-1
(value never reached). For each line I usematch
string function to detect indent size, by finding position of 1st non-white-space character. If indent is same as previous I only add current line to arrayarr
under key being number of line, otherwise I save indent size in variableindent
, output all from array in predefined order, cleanse array (so it become empty) and add current line to array. After all lines are processed (END
) I output content of arrayarr
.(tested in GNU Awk 5.1.0)
The man-page of the basic UNIX
sort
commands starts with:Why not try, using
sort -b
?