假设我有这个(使用我显示的格式,没有换行符)
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 还不是图灵完备的(尽管扩展可能是)所以你可能可以写一个解析器...
或者您可以编写一个基于堆栈的解析器来;
在结束后添加 a )
... 并处理错误的语法。
相反,您可能想使用更有可能无法错误匹配的东西。例如,此代码选取该INSERT INTO
语句并;
在其前面添加一个,并记住在最后添加一个。
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
2)假设有两种方式VALUES
可以存在:
- 没有内在的 VALUES中
()
不会有'
- 带有内部的 VALUES
()
将开始于('
并结束于')
perl -pe "s/VALUES\s*\([^')]*\)/$&;/g ; s/VALUES\s*\('.*?'\)/$&;/g" file