我需要从postgres写一个文件到磁盘,后面有一个反斜杠的字符串,后跟一个正斜杠\/
与此类似的代码无效:
drop table if exists test;
create temporary table test (linetext text);
insert into test values ('\/\/foo foo foo\/bar\/bar');
copy (select linetext from test) to '/filepath/postproductionscript.sh';
上面的代码产生\\/\\/foo foo foo\\/bar\\/bar
...它会插入一个额外的反斜杠。
当您查看临时表时,该字符串被正确地视为\/\/
,因此我不确定文本在何处或何时更改为\\/\\/
我已尝试将字符串前的\
,E变体加倍,而在没有运气的情况下加上quote_literal()。
我注意到这里找到了一个解决方案Postgres Manual
运行Postgres 9.2,编码为UTF-8。
答案 0 :(得分:2)
问题是COPY
不打算写出纯文本文件。它旨在写出COPY
可以回读的文件。它使用的半内部编码会产生一些反斜杠转义。
对于您想要做的事情,您需要编写一些自定义代码。使用普通客户端库来读取查询结果并将其写入文件,或者,如果要在服务器中执行,请使用PL / Perl或PL / Python之类的东西。
答案 1 :(得分:0)
仅当stringliteral以E为前缀时才会识别\ excaping,否则会遵循standard_conforming_strings设置(或类似)(ANSI-SQL有一种不同的字符串转义方式,可能源于COBOL; - )。
drop table if exists test;
create temporary table test (linetext text);
insert into test values ( E'\/\/foo foo foo\/bar\/bar');
copy (select linetext from test) to '/tmp/postproductionscript.sh';
更新:一个丑陋的黑客是使用.csv格式,仍然使用\ t作为分隔符。 作为shebang标题的#!/ bin / sh应该是一个特征
-- without a header line
drop table if exists test;
create temporary table test (linetext text);
insert into test values ( '\/\/foo foo foo\/bar\/bar');
copy (select linetext AS "#linetext" from test) to '/tmp/postproductionscript_c.sh'
WITH CSV
DELIMITER E'\t'
;
-- with a shebang header line
drop table if exists test;
create temporary table test (linetext text);
insert into test values ( '\/\/foo foo foo\/bar\/bar');
copy (select linetext AS "#/bin/sh" from test) to '/tmp/postproductionscript_h.sh'
WITH CSV
HEADER
DELIMITER E'\t'
;