我正在尝试转换以下(MS-SQL)字符串
INSERT INTO Foo (Bar) VALUES (CAST('1958-08-22 21:00:00.000' AS DateTime))
到SQLite语法
INSERT INTO Foo (Bar) VALUES (-358491600)
我使用以下sed
参数成功完成此操作:
sed -r "s#cast\('(.*)' as datetime\)#date -d '\1' '+%s'#ige"
(调用date -d '...' '+%s'
将日期转换为纪元)
在整行上运行相同的命令:
echo "INSERT INTO Foo (Bar) values (cast('1958-08-22 21:00:00.000' as datetime))" | \
sed -r "s#cast\('(.*)' as datetime\)#date -d '\1' '+%s'#ige"
...产生错误:sh: 1: Syntax error: "(" unexpected
根据我追踪的情况,括号会导致线路失败:
echo "() cast('1958-08-22 21:00:00.000' as datetime)" | \
sed -r "s#cast\('(.*)' as datetime\)#date -d '\1' '+%s'#ige"
正确删除e
开关可转换命令。我做错了什么?
答案 0 :(得分:2)
如果您在strace
下运行命令以查看将执行哪些exacly,您将看到以下内容:
$ echo "INSERT INTO Foo (Bar) values (cast('1958-08-22 21:00:00.000' as datetime))" | strace -ff sed -r "s#cast\('(.*)' as datetime\)#date -d '\1' '+%s'#ige" 2>&1 | grep 'execve('
execve("/bin/sed", ["sed", "-r", "s#cast\\('(.*)' as datetime\\)#dat"...], [/* 27 vars */]) = 0
[pid 8179] execve("/bin/sh", ["sh", "-c", "INSERT INTO Foo (Bar) values (da"...], [/* 27 vars */] <unfinished ...>
这意味着sed
不仅尝试执行与模式匹配的文本而且还尝试执行整行。所以,可能,你不能用sed
执行此操作(我很高兴,如果我错了。)
所以,我建议从文件中收集所有日期,转换它们然后逐个替换。例如:
$ cat q.sql
INSERT INTO Foo (Bar) VALUES (CAST('1958-08-22 21:00:00.000' AS DateTime));
INSERT INTO Foo (Bar) VALUES (CAST('1958-08-23 22:00:00.000' AS DateTime));
$ sed "s|.*CAST('\([^']\+\)'.*|\1|" q.sql | while read DATE; do sed -i "s|$DATE|$(date -d "$DATE" '+%s')|" q.sql; done
$ cat q.sql
INSERT INTO Foo (Bar) VALUES (CAST('-358495200' AS DateTime));
INSERT INTO Foo (Bar) VALUES (CAST('-358405200' AS DateTime));
答案 1 :(得分:2)
带有ge
标志的sed完成了您的工作:
sed -r 's/(.*CAST[^\x27]*\x27)([^\x27]*)(\x27 AS DateTime.*)/
echo "\1"$(date -d"\2" "+%s")"\3"/ge' file
以你的例子:
kent$ cat f
INSERT INTO Foo (Bar) VALUES (CAST('1958-08-22 21:00:00.000' AS DateTime));
INSERT INTO Foo (Bar) VALUES (CAST('1958-08-23 22:00:00.000' AS DateTime));
kent$ sed -r 's/(.*CAST[^\x27]*\x27)([^\x27]*)(\x27 AS DateTime.*)/echo "\1"$(date -d"\2" "+%s")"\3"/ge' file
INSERT INTO Foo (Bar) VALUES (CAST('-358488000' AS DateTime));
INSERT INTO Foo (Bar) VALUES (CAST('-358398000' AS DateTime));
如果您不希望输出As DateTime
,只需制作合适的群组,我认为您可以管理它。