如何将当前输入文件名合并到我的Pig Latin脚本中?

时间:2012-03-17 16:04:25

标签: apache-pig

我正在处理来自一组文件的数据,这些文件包含日期戳作为文件名的一部分。文件中的数据不包含日期戳。我想处理文件名并将其添加到脚本中的一个数据结构中。有没有办法在Pig Latin(PigStorage的扩展可能?)中做到这一点,还是我需要预先使用Perl等预处理所有文件?

我想象如下:

-- Load two fields from file, then generate a third from the filename
rawdata = LOAD '/directory/of/files/' USING PigStorage AS (field1:chararray, field2:int, field3:filename);

-- Reformat the filename into a datestamp
annotated = FOREACH rawdata GENERATE
  REGEX_EXTRACT(field3,'*-(20\d{6})-*',1) AS datestamp,
  field1, field2;

请注意LOAD语句中的特殊“filename”数据类型。似乎它必须在那里发生,因为一旦数据被加载,回到源文件名就太晚了。

4 个答案:

答案 0 :(得分:14)

您可以通过指定-tagsource使用PigStorage,如下所示

A = LOAD 'input' using PigStorage(',','-tagsource'); 
B = foreach A generate INPUT_FILE_NAME; 

每个元组中的第一个字段将包含输入路径(INPUT_FILE_NAME)

根据API文档http://pig.apache.org/docs/r0.10.0/api/org/apache/pig/builtin/PigStorage.html

答案 1 :(得分:13)

Pig wiki作为PigStorageWithInputPath的一个例子,它在另一个chararray字段中有文件名:

示例

A = load '/directory/of/files/*' using PigStorageWithInputPath() 
    as (field1:chararray, field2:int, field3:chararray);

UDF

// Note that there are several versions of Path and FileSplit. These are intended:
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigSplit;
import org.apache.pig.builtin.PigStorage;
import org.apache.pig.data.Tuple;

public class PigStorageWithInputPath extends PigStorage {
   Path path = null;

   @Override
   public void prepareToRead(RecordReader reader, PigSplit split) {
       super.prepareToRead(reader, split);
       path = ((FileSplit)split.getWrappedSplit()).getPath();
   }

   @Override
   public Tuple getNext() throws IOException {
       Tuple myTuple = super.getNext();
       if (myTuple != null)
          myTuple.append(path.toString());
       return myTuple;
   }
}

答案 2 :(得分:3)

在Pig 0.12.0中不推荐使用

-tagSource。 而是使用

  

-tagFile - 将输入源文件名附加到每个元组的开头。
  -tagPath - 将输入源文件路径追加到每个元组的开头。

try{
   db.insertOrThrow(table, columnHack, values);
} catch (SQLiteConstraintException e){
   Toast.makeText(context, "Unable to insert values.", Toast.LENGTH_SHORT).show();
}

将为您提供第一列的完整文件路径

A = LOAD '/user/myFile.TXT' using PigStorage(',','-tagPath'); 
DUMP A  ;

参考:http://pig.apache.org/docs/r0.12.0/api/org/apache/pig/builtin/PigStorage.html

答案 3 :(得分:1)

在Bash和PigLatin中执行此操作的方法可在以下位置找到:How Can I Load Every File In a Folder Using PIG?

我最近一直在做的事情,并且发现更清洁的是在Python中嵌入Pig。那就是让你抛出各种变量,等等。一个简单的例子是:

#!/path/to/jython.jar                                    

# explicitly import Pig class                                                                         
from org.apache.pig.scripting import Pig

# COMPILE: compile method returns a Pig object that represents the pipeline                           
P = Pig.compile(
               "a = load '$in'; store a into '$out';")

input = '/path/to/some/file.txt'
output = '/path/to/some/output/on/hdfs'

# BIND and RUN                                                                                        
results = P.bind({'in':input, 'out':output}).runSingle()

if results.isSuccessful() :
    print 'Pig job succeeded'
else :
    raise 'Pig job failed'

如果您有兴趣,请查看Julien Le Dem's great slides作为对此的介绍。 http://pig.apache.org/docs/r0.9.2/cont.pdf还有大量文档。