Скажем, у меня есть это (с форматом, который я показываю, без новых строк)
INSERT INTO `somthing` (`something`) VALUES (1) INSERT INTO `somthing` (`somethingelse`) VALUES ('something with a (paranthesis) in it') INSERT INTO `somthing` (`something`) VALUES (3) INSERT INTO `somthing` (`something`) VALUES (4)
Я хочу, чтобы вывод был
INSERT INTO `somthing` (`something`) VALUES (1); INSERT INTO `somthing` (`somethingelse`) VALUES ('something with a (paranthesis) in it'); INSERT INTO `somthing` (`something`) VALUES (3); INSERT INTO `somthing` (`something`) VALUES (4);
Чтобы это были легитимные SQL-запросы. Я пробовал это в sed:
sed 's/\(VALUES ([^)]*)\)/\1;/g')
Что работает, за исключением случаев, когда внутри значений есть парантезы, я не уверен, что нужно сделать, чтобы исправить это. По сути, я хочу добавить точку с запятой в конец (.*)
, (последний )
), если перед ним написано VALUES
.
Вы можете решить проблему, сопоставив другую часть оператора, например,
sed -e 's/\(VALUES (`[^`]*`)\)/\1;/g' \
-e "s/\(VALUES ('[^']*')\)/\1;/g" \
-e 's/\(VALUES ([0-9]*)\)/\1;/g'
Это не будет зависеть от того, что находится внутри круглых скобок.
Нет простого шаблона, который был бы верным в любых обстоятельствах; вам нужно будет написать синтаксический анализатор SQL, чтобы определить, когда конец оператора должен быть ... и даже тогда вам нужно будет надеяться, что не произойдет никакого особого волшебства. Теперь ANSI SQL не является полным по Тьюрингу (хотя могут быть и расширения), поэтому вы, вероятно, могли бы написать синтаксический анализатор ...
Или вы могли бы написать синтаксический анализатор на основе стека, чтобы добавить ;
после закрытия )
... и обрабатывать неверный синтаксис.
Вместо этого вы можете использовать что-то, что с большей вероятностью не совпадет с ошибками. Например, этот код берет оператор INSERT INTO
и помещает перед ним ;
, не забывая добавить его в самом конце.
sed -e 's/\( INSERT INTO `somthing` (`something`) VALUES (\)/;\1/g' -e 's/$/;/'
Очевидно, это не удалось бы, если бы во вставленных данных была эта конкретная строка ...
1) Предполагая, что окончание )
из VALUES
будет сопровождаться ключевым словом INSERT
или концом строки, как указано в примере ввода, предоставленном в вопросе
perl -pe 's/VALUES\s*\(.*?\)(?=\s*INSERT|$)/$&;/g' file
2) Предполагается, что существует два способа ЗНАЧЕНИЯ
могут присутствовать:
()
не будут иметь в себе '
()
будут начинаются как ('
и заканчиваются на ')
perl -pe "s/VALUES\s*\([^')]*\)/$&;/g ; s/VALUES\s*\('.*?'\)/$&;/g" file