6

我们正在将 Postgres 9.3 中的数据导出到一个文本文件中,以供 Spark 摄取。

我们希望使用 ASCII 31 字段分隔符而不是 \t 作为分隔符,这样我们就不必担心转义问题。

我们可以在这样的 shell 脚本中这样做:

#!/bin/bash
DELIMITER=$'\x1F'
echo "copy ( select * from table limit 1) to STDOUT WITH DELIMITER '${DELIMITER}'" | (psql ...) > /tmp/ascii31

但是我们想知道,是否可以在“纯”postgres 中指定不可打印的字形作为分隔符?

编辑:我们尝试使用每个http://www.postgresql.org/docs/9.3/static/sql-syntax-lexical.html的 postgres 转义约定

warehouse=> copy ( select * from table limit 1) to STDOUT WITH DELIMITER '\x1f';

并收到

ERROR:  COPY delimiter must be a single one-byte character
4

3 回答 3

12

尝试在您尝试用作分隔符的序列之前添加 E。例如E'\x1f',而不是'\x1f'. 如果没有 E PostgreSQL 将读取'\x1f'为四个单独的字符而不是十六进制转义序列,因此会出现错误消息。

有关更多信息,请参阅PostgreSQL 手册中的“带有 C 样式转义的字符串常量”

于 2015-09-09T19:37:15.373 回答
1

根据我的测试,以下两项工作:

echo "copy (select 1 a, 2 b) to stdout with delimiter u&'\\001f'"| psql;

echo "copy (select 1 a, 2 b) to stdout with delimiter e'\\x1f'"| psql;
于 2015-02-17T18:49:37.630 回答
0

我已经从 Actian Matrix(Amazon Redshift 的一个分支,postgres 的两个派生)中提取了一个小文件,将这个符号用于 ASCII 字符代码 30,“记录分隔符”。

unload ('SELECT btrim(class_cd) as class_cd, btrim(class_desc) as class_desc
FROM transport.stg.us_fmcsa_carrier_classes')
to '/tmp/us_fmcsa_carrier_classes_mk4.txt'
delimiter as '\036' leader;

这是该文件在 VI 中的外观示例:

C^^Private Property
D^^Private Passenger Business
E^^Private Passenger Non-Business

然后我通过 sftp 将此文件移动到托管 PostgreSQL 9.5 的机器上,并使用以下复制命令,这似乎运行良好:

copy fmcsa.carrier_classes
from '/tmp/us_fmcsa_carrier_classes_mk4.txt'
delimiter u&'\001E'; 

postgres 的每个派生词,以及 postgres 本身似乎更喜欢稍微不同的符号。可惜我们没有统一的标准!

于 2016-04-25T19:22:59.033 回答