Pig将制表符(\t)作为动态CSV解析的参数

0 投票
1 回答
525 浏览
提问于 2025-04-18 00:35

我正在处理一些数据文件,这些文件里的数据是用不同的分隔符分开的,比如 CSV 用逗号(','),TSV 用制表符('\t'),还有分号(';')。我现在的方法可以处理逗号和分号,但处理制表符时遇到了问题。我该怎么把制表符作为参数传给 Pig 呢?

这是我的 Python 代码:

delimiter = '\t'
cmd = 'pig -f sample.pig -p file='+data_file +' -p delimiter=' + delimiter
subprocess.Popen(cmd, shell=True, stderr=subprocess.STDOUT) 

Pig

-- REGISTER 'piggybank.jar'
-- may use CSVExcelStorage in future
results = LOAD '$file' USING PigStorage('$delimiter'); 

我遇到了以下异常:

2014-03-31 03:26:41,412 [main] INFO  org.apache.pig.tools.parameters.ParameterSubstitutionPreprocessor - The parameter: "delimiter= " cannot be parsed by Pig. Please double check it
2014-03-31 03:26:41,412 [main] INFO  org.apache.pig.tools.parameters.ParameterSubstitutionPreprocessor - Parser give the follow error message:
2014-03-31 03:26:41,413 [main] INFO  org.apache.pig.tools.parameters.ParameterSubstitutionPreprocessor - Encountered "<EOF>" at line 1, column 16.
Was expecting one of:
    <IDENTIFIER> ...
    <OTHER> ...
    <LITERAL> ...
    <SHELLCMD> ...

1 个回答

1

这里不要使用 shell;因为制表符对 shell 来说是空白字符,并不会作为参数传递:

cmd = ['pig', '-f', 'sample.pig', '-p', 'file=' + data_file, '-p',
       'delimiter=' + delimiter]
subprocess.Popen(cmd, stderr=subprocess.STDOUT) 

注意,我把 shell 保持为默认的 False;当你可以直接调用 pig 时,就没有必要把这个命令传给 shell。把 shell 设置为 False 后,应该传入一个参数列表。

即便如此,我 觉得 你可能需要给 pig 传递一个序列 \t(两个字符):

delimiter = '\\t'

或者使用原始字符串:

delimiter = r'\t'

如果这样还不行,你就得特殊处理了;我只看过 pig latin 表达式参考,所以这个没有经过测试,但我会使用条件表达式和 TAB 作为命令行参数:

results = LOAD '$file' USING PigStorage('$delimiter' == 'TAB' ? '\t' : '$delimiter');

在 Python 中:

delimiter = 'TAB'

撰写回答