私がこれを持っているとしましょう(改行なしで私が示す形式を使って)
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
答え1
すべての状況に合う単純なパターンはありません。ステートメントの終わりを決定するには、SQLパーサーを作成する必要があります。しなければならないはい…それでも特別な魔法が起こらないことを望む必要があります。 ANSI SQLはチューリング完了ではないので(拡張は可能です)できるパーサーを作成してください...
あるいは、スタックベースのパーサーを作成して、;
最後の後に...を追加し、)
誤った構文を処理することもできます。
代わりに、間違って一致しない可能性が高いものを使用したい場合があります。たとえば、このコードはステートメントを取得し、INSERT INTO
その;
前に1つを追加し、最後に1つを追加することを覚えています。
sed -e 's/\( INSERT INTO `somthing` (`something`) VALUES (\)/;\1/g' -e 's/$/;/'
挿入されたデータに特定の文字列があると、明らかに失敗します。
答え2
たとえば、問い合わせの異なる部分を一致させることで問題を解決できます。
sed -e 's/\(VALUES (`[^`]*`)\)/\1;/g' \
-e "s/\(VALUES ('[^']*')\)/\1;/g" \
-e 's/\(VALUES ([0-9]*)\)/\1;/g'
括弧内の内容に依存しません。
答え3
1)提供された入力例に示すように、仮説の末尾にはキーワードまたは行末が)
続きます。VALUES
INSERT
perl -pe 's/VALUES\s*\(.*?\)(?=\s*INSERT|$)/$&;/g' file
VALUES
2)それが存在できる2つの方法があると仮定します。
- 本質的な価値はあり
()
ません。'
- 内部値は
()
次から始まり、('
終了します。')
perl -pe "s/VALUES\s*\([^')]*\)/$&;/g ; s/VALUES\s*\('.*?'\)/$&;/g" file