我有一个SQL文件,其中包含许多INSERT语句,但它们都合并在一行上。 我试图用sed在不同的线路上分开它们,但是我不能使它工作。 这是我正在使用的命令:
sed 's/);INSERT/);\nINSERT/' myfile.sql
但是这个命令不起作用。 它出什么问题了? 我该如何解决?
在正则expression式的末尾添加一个“g”,告诉它在所有匹配上工作,而不是仅仅find第一个匹配。
sed 's/);INSERT/);\nINSERT/g' myfile.sql
文件从哪里来的?
如果是Mac,那么在分号后面可能会出现回车符(“\ r”或ASCII 0x13)。 Mac使用CR作为行分隔符,而* nix使用换行符(又名“换行”(“\ n”或ASCII 0x0a))。
MS-Dos / Windows使用两个字符序列CR / LF(“\ r \ n”)来分隔行。
另外,如果input全部是一行,那么s / search / replace /将只replace行上的第一个匹配。 您需要使用g修饰符来使其成为“全局”search和replace。
我的猜测是,该文件是从Mac,因为你说这只是一行…一个Windows文件仍然会被视为多行(因为有一个\ n为unix看到)。
尝试像这样:
sed's); [\ n \ r] * INSERT /); \ nINSERT / g'myfile.sql
这将匹配您的string与紧接在分号后面的零个或多个\ n和/或\ r个字符。 还要注意/ g修饰符。
如果失败了,我会倾向于尝试perl而不是sed(但是我更喜欢perl RE)。 你可以把整个文件写成一个标量string,并使用/ s和/ g修饰符几乎忽略行尾。 你也可以使用\ R字符类匹配几乎任何已知的行结尾 – 根据perlre手册页,它匹配:
(> \ X0D \ X0A |?[\ x0A- \ X0C \ X85 \ X {2028} \ X {2029}])
。
sed 's/);INSERT/);^MINSERT/g' myfile.sql | control-V control-M