2012-03-17 11 views
13

Przetwarzam dane z zestawu plików zawierających datownik jako część nazwy pliku. Dane w pliku nie zawierają znacznika daty. Chciałbym przetworzyć nazwę pliku i dodać go do jednej ze struktur danych w skrypcie. Czy jest jakiś sposób, aby to zrobić w Pig Latin (może być rozszerzeniem do PigStorage?) Lub czy muszę wstępnie przetworzyć wszystkie pliki używając Perla lub podobnego?Jak mogę wprowadzić bieżącą nazwę pliku wejściowego do mojego skryptu łacińskiego?

mogę sobie wyobrazić coś jak następuje:

-- 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; 

zanotować specjalne „filename” typ danych w sprawozdaniu obciążenia. Wygląda na to, że musi się tam zdarzyć, ponieważ po załadowaniu danych jest już za późno, aby powrócić do źródłowej nazwy pliku.

Odpowiedz

13

Wiki wieprzowych przykład PigStorageWithInputPath który miał nazwę pliku w dodatkowym obszarze chararray:

przykładu

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; 
    } 
} 
1

taki sposób, aby to zrobić, w Basha i PigLatin można znaleźć pod adresem: How Can I Load Every File In a Folder Using PIG?.

Co ostatnio robiłem i uważam, że jest o wiele czystsze, to osadzanie Pig w Pythonie. To pozwala ci wyrzucać różne zmienne i takie między nimi. Prostym przykładem jest:

#!/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' 

Wystarczy popatrzeć na Julien Le Dem's great slides jako wprowadzenie do tego, jeśli jesteś zainteresowany. Jest też mnóstwo dokumentacji pod adresem http://pig.apache.org/docs/r0.9.2/cont.pdf.

3

-tagSource jest przestarzałe w Pig 0.12.0. Zamiast tego użyj

-tagFile - Dołącza nazwę pliku wejściowego do początku każdej krotki.
-tagPath - Dodaje ścieżkę pliku wejściowego do początku każdej krotki.

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

daje pełną ścieżkę dostępu do pliku jako pierwszej kolumny

(hdfs://myserver/user/blo/input/2015.TXT,439,43,05,4,NAVI,PO,P&C,P&CR,UC,40) 

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

Powiązane problemy