2012-11-14 15 views
16

Muszę połączyć dwa pliki na dwóch polach. Jednak powinienem pobrać wszystkie wartości w pliku 1, nawet jeśli połączenie nie powiedzie się tak jak lewe sprzężenie zewnętrzne.Lewe sprzężenie zewnętrzne na dwóch plikach w unixie

pliku 1:

01|a|jack|d 
02|b|ron|c 
03|d|tom|e 

Plik 2:

01|a|nemesis|f 
02|b|brave|d 
04|d|gorr|h 

wyjściowe:

01|a|jack|d|nemesis|f 
02|b|ron|c|brave|d 
03|d|tom|e|| 

Odpowiedz

19

To join -t '|' file1 file2 -a1

opcje używane:

t: Ogranicznik.
a: Decyduje o numerze pliku, z którego niepowiązane wiersze muszą zostać wydrukowane.

join -t '|' file1 file2 -a2 zrobiłby prawe złącze zewnętrzne.

Run Sample

[[email protected] test]$ cat f1 
    01|a|jack|d 

    02|b|ron|c 

    03|d|tom|e 
    [[email protected] test]$ cat f2 
    01|a|nemesis|f 

    02|b|brave|d 

    04|d|gorr|h 
    [[email protected] test]$ join -t '|' f1 f2 -a1 
    01|a|jack|d|a|nemesis|f 

    02|b|ron|c|b|brave|d 

    03|d|tom|e 
+1

masz rację, twoje wyjście dopasowuje swoją moc. sprawa zamknięta. Powodzenia wszystkim. – shellter

+0

@shellter. Nie do końca. Brakuje rury na końcu rekordu bez dopasowania, które jest adresowane w poście. Mimo wszystko, podaję to za bycie strategią, która ma skłonić większość ludzi do szukania funkcji dołączania zewnętrznego Linuksa. –

4

Aby to zrobić dokładnie to, co pytanie pyta jest nieco bardziej skomplikowana, niż poprzedniej odpowiedzi i wymaga mniej więcej tak:

sed 's/|/:/2' file1 | sort -t: >file1.tmp 
sed 's/|/:/2' file2 | sort -t: >file2.tmp 
join -t':' file1.tmp file2.tmp -a1 -e'|' -o'0,1.2,2.2' | tr ':' '|' 

Unix dołączyć może tylko dołączyć na pojedyncze pole AFAIK, więc musisz użyć plików, które używają innego separatora, aby "połączyć dwa pliki na dwóch polach", w tym przypadku pierwsze dwa pola. Użyję dwukropka :, ale jeśli w jakimkolwiek wejściu istnieje :, będziesz musiał użyć czegoś innego, na przykład znak tabulacji może być lepszym wyborem do wykorzystania w produkcji. Również ponownie sortuję dane wyjściowe na nowym polu złożonym, sort -t:, które dla przykładowych plików wejściowych robi różnicę, ale dla danych rzeczywistych. sed 's/|/:/2' zastępuje drugie wystąpienie potoku z dwukropkiem w każdej linii w pliku.

file1.tmp

01|a:jack|d 
02|b:ron|c 
03|d:tom|e 

file2.tmp

01|a:nemesis|f 
02|b:brave|d 
04|d:gorr|h 

Teraz używamy join wyjście filtrowane przez tr z kilku bardziej zaawansowanych opcji:

  • -t':' określających dwukropek tymczasowy ogranicznik
  • -a1 lewe sprzężenie zewnętrzne
  • -e'|' określa ciąg zastępczy nieudanych połączeń, w zasadzie końcowy separator wyjściowy N-1, gdzie N jest liczbą rozdzielonych potokami pól połączonych po prawej stronie dwukropka w pliku file2.tmp. W tym przypadku N = 2, więc jeden znak potoku.
  • -o'0,1.2,2.2' określa format wyjściowy:
    • 0 przyłączenia pola
    • 1.2 pole 2 file1.tmp, czyli wszystko w porządku okrężnicy
    • 2.2 pole 2 file2.tmp
  • tr ':' '|' Na koniec tłumaczymy dwukropki z powrotem do potoków dla ostatecznego wyniku.

Wyjście teraz mecze wyjście próbka pytanie dokładnie którego poprzednia odpowiedź nie robić:

01|a|jack|d|nemesis|f 
02|b|ron|c|brave|d 
03|d|tom|e|| 
+0

Przemyślana odpowiedź i doskonałe wyjaśnienie każdego szczegółu. –

Powiązane problemy