我正在处理来自一组文件的数据,这些文件包含日期戳作为文件名的一部分。文件中的数据不包含日期戳。我想处理文件名并将其添加到脚本中的一个数据结构中。有没有办法在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”数据类型。似乎它必须在那里发生,因为一旦数据被加载,回到源文件名就太晚了。
答案 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)
-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还有大量文档。