Использование sed для очистки выходных данных SchemaSync - PullRequest
1 голос
/ 02 апреля 2019

Я создал небольшой образец того, с чем я сейчас работаю.Я пытаюсь правильно заключить в кавычки значения DEFAULT, в частности значение # 2 DEFAULT ONE должно быть заключено в кавычки как DEFAULT 'ONE':

#1 CREATE TABLE `table` (`column` int(10) unsigned DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
#2 ALTER TABLE `table` MODIFY COLUMN `column2` enum('ONE','TWO') NOT NULL DEFAULT ONE AFTER `column1`;
#3 ALTER TABLE `table` MODIFY COLUMN `column` varchar(64) NOT NULL DEFAULT '' FIRST;

В настоящее время я использую следующую строку против вышеуказанных строк, чтобы исправить строку# 2:

sed "s/DEFAULT \([a-zA-Z0-9_.]*\)/DEFAULT '\1'/g"

Это вывод, который я получаю:

#1 CREATE TABLE `table` (`column` int(10) unsigned DEFAULT 'NULL') ENGINE=InnoDB DEFAULT 'CHARSET'=utf8mb4 COLLATE=utf8mb4_unicode_ci;
#2 ALTER TABLE `table` MODIFY COLUMN `column2` enum('ONE','TWO') NOT NULL DEFAULT 'ONE' AFTER `column1`;
#3 ALTER TABLE `table` MODIFY COLUMN `column` varchar(64) NOT NULL DEFAULT '''' FIRST;

Как вы можете видеть, он исправляет строку № 2, но № 1 и № 3 теперь имеют проблемы.

#1 DEFAULT 'NULL'    (should remain DEFAULT NULL)
#1 DEFAULT 'CHARSET' (should remain DEFAULT CHARSET)
#2 DEFAULT 'ONE'     (GOOD!)
#3 DEFAULT ''''      (should remain DEFAULT '')

Есть ли способ настроить sed, чтобы игнорировать определенные шаблоны, такие как DEFAULT NULL или DEFAULT CHARSET или DEFAULT ''?

sed "s/DEFAULT (not followed by NULL|CHARSET|'')\([a-zA-Z0-9_.]*\)/DEFAULT '\1'/g"

Или, может быть, есть лучший подход?

Спасибо!

Ответы [ 3 ]

2 голосов
/ 02 апреля 2019

Если Perl ваш выбор, пожалуйста, попробуйте:

perl -pe "s/(DEFAULT) (?!(NULL|CHARSET|''))([a-zA-Z0-9_]+)/\1 '\3'/g" file

Выход:

#1 CREATE TABLE `table` (`column` int(10) unsigned DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
#2 ALTER TABLE `table` MODIFY COLUMN `column2` enum('ONE','TWO') NOT NULL DEFAULT 'ONE' AFTER `column1`;
#3 ALTER TABLE `table` MODIFY COLUMN `column` varchar(64) NOT NULL DEFAULT '' FIRST;
1 голос
/ 02 апреля 2019

Попробуйте:

sed -E "s/DEFAULT (NULL|CHARSET)/DEFAULT_\1/g; s/DEFAULT ([[:alnum:]_.]+)/DEFAULT '\1'/g; s/DEFAULT_(NULL|CHARSET)/DEFAULT \1/g" file

Это работает в три этапа:

  1. s/DEFAULT (NULL|CHARSET)/DEFAULT_\1/g

    Это скрывает значения DEFAULT, которые вы не 'я не хочу менять.

  2. s/DEFAULT ([[:alnum:]_.]+)/DEFAULT '\1'/g

    Это меняет значения, которые вы хотите изменить.

    Обратите внимание, что я изменил * до +.Это означает, что пустые строки не будут сопоставлены.Это решает проблему в строке № 3.

    Я также изменил [a-zA-Z0-9] на [:alnum:], чтобы регулярное выражение соответствовало всем буквенно-цифровым символам в безопасном для юникода виде.(Если это не то, что вы хотели, просто измените эту часть обратно.)

  3. s/DEFAULT_(NULL|CHARSET)/DEFAULT \1/g

    Это вернет те, которые вы не хотитеизменить.

Этот подход предполагает, что ни DEFAULT_NULL, ни DEFAULT_CHARSET не появятся в вашем фактическом вводе.Исходя из того, что вы уже показали, это выглядит как безопасное предположение.

Пример

С вашим входным файлом:

$ cat file
#1 CREATE TABLE `table` (`column` int(10) unsigned DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
#2 ALTER TABLE `table` MODIFY COLUMN `column2` enum('ONE','TWO') NOT NULL DEFAULT ONE AFTER `column1`;
#3 ALTER TABLE `table` MODIFY COLUMN `column` varchar(64) NOT NULL DEFAULT '' FIRST;

Наша команда выдает:

$ sed -E "s/DEFAULT (NULL|CHARSET)/\n\1/g; s/DEFAULT ([[:alnum:]_.]+)/DEFAULT '\1'/g; s/\n(NULL|CHARSET)/DEFAULT \1/g" file
#1 CREATE TABLE `table` (`column` int(10) unsigned DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
#2 ALTER TABLE `table` MODIFY COLUMN `column2` enum('ONE','TWO') NOT NULL DEFAULT 'ONE' AFTER `column1`;
#3 ALTER TABLE `table` MODIFY COLUMN `column` varchar(64) NOT NULL DEFAULT '' FIRST;
0 голосов
/ 02 апреля 2019

С GNU awk для нескольких символов RS:

awk -v RS='DEFAULT \\w+' -v ORS= '
    RT { split(RT,rt); if (rt[2] !~ /^(NULL|CHARSET)$/) RT=rt[1]" \047"rt[2]"\047" }
    { print $0 RT }
' file
#1 CREATE TABLE `table` (`column` int(10) unsigned DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
#2 ALTER TABLE `table` MODIFY COLUMN `column2` enum('ONE','TWO') NOT NULL DEFAULT 'ONE' AFTER `column1`;
#3 ALTER TABLE `table` MODIFY COLUMN `column` varchar(64) NOT NULL DEFAULT '' FIRST;
...