2013-02-20 9 views
45

Wiele osób były bardzo pomocne, zamieszczając następujące rozwiązanie AWK'ing wielu plików wejściowych naraz:Korzystanie AWK do przetwarzania wejściowego z wielu plików

$ awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' file2 file1 

Działa to dobrze, ale zastanawiałem się, czy ktoś mi może mi wyjaśnić, dlaczego? Uważam, że składnia AWK jest trochę trudna do zdobycia i liczyła na to, że ktoś nie będzie miał nic przeciwko zerwaniu mi fragmentu kodu.

Odpowiedz

50
awk 'FNR==NR{a[$1]=$2 FS $3;next} 

tutaj zajmiemy się 1. wejściem (plik2). powiedzmy, FS to spacja, budujemy tablicę (a) w górę, indeks to kolumna1, wartość to column2 " " column3 oznacza, że ​​ta część kodów działa tylko dla pliku2. można człowiekowi gawk sprawdzić jakie są NR i FNR

{ print $0, a[$1]}' file2 file1 

Kiedy NR != FNR nadszedł czas, aby przetwarzać dane wejściowe, 2nd plik1. tutaj drukujemy linię pliku1, i bierzemy kolumnę1 jako indeks, znajdźmy wartość w tablicy (a) drukuj. Innymi słowy, plik1 i plik2 są połączone kolumną1 w obu plikach.

NR i FNR na krótko,

1st input has 5 lines 
2nd input has 10 lines, 

NR would be 1,2,3...15 
FNR would be 1...5 then 1...10 

widać trick FNR==NR czeku.

+0

Kent, doskonałe wyjaśnienie; Dziękuję Ci bardzo. Nie zdawałem sobie sprawy, że "FNR == NR" tworzył rodzaj stwierdzenia "jeśli". Właśnie tego potrzebuję, aby móc iść naprzód. Wielkie dzięki za poświęcenie czasu na pomoc! – jkovba

8

Znalazłem to pytanie/odpowiedź w Google i wygląda na to, że odnosi się do bardzo określonego zestawu danych znalezionych w innym pytaniu (How to merge two files using AWK?). Poniżej znajduje się odpowiedź, której szukałem (i myślę, że większość ludzi byłaby), tj. Po prostu łączenie każdej linii z dwóch różnych plików przy użyciu AWK. Choć prawdopodobnie można korzystać z niektórych narzędzi UNIX jak przyłączenia lub pasty, AWK jest oczywiście znacznie bardziej elastyczny i potężny, jeśli sygnał wyjściowy jest inny, za pomocą razie oświadczenia, lub zmieniając OFS (które mogą być bardziej trudne w zależności od narzędzia, patrz poniżej), na przykład, zmieniając wydatek znacznie bardziej wyrazisty sposób (istotną uwagę na skrypterów powłoki)

dla prostej linii po linii łączenie:

awk 'FNR==NR { a[FNR""] = $0; next } { print a[FNR""], $0 }' file1 file2.

Emuluje to funkcję tablicy indeksowanej numerycznie (AWK ma tylko tablice asocjacyjne) za pomocą niejawnej konwersji typów. Jest względnie ekspresyjny i łatwy do zrozumienia.

Korzystanie dwa pliki o nazwie test1 i test2 z następującymi liniami:

test1:

line one 
line two 
line three 

test2:

line four 
line five 
line six 

uzyskać ten wynik:

line one line four 
line two line five 
line three line six 

W zależności od ho Jeśli chcesz dołączyć wartości między kolumnami na wyjściu, możesz wybrać odpowiedni separator pól wyjściowych. Oto przykład z elipsami (...) Oddzielające kolumny:

awk 'BEGIN { OFS="..."} FNR==NR { a[(FNR"")] = $0; next } { print a[(FNR"")], $0 }' test1 test2

Plonowanie ten wynik:

line one...line four 
line two...line five 
line three...line six 

Mam nadzieję, że przynajmniej ten inspiruje wszystkich do skorzystania z mocą AWK!

+4

Jeśli celem jest tylko dołączanie kolumn obok siebie, bardzo proste jest użycie polecenia 'paste'. – biocyberman

Powiązane problemy