2012-11-07 14 views
5

Szuka połączenia wewnętrznego w dwóch różnych plikach tekstowych. Zasadniczo szukam wewnętrznego odpowiednika programu łączącego GNU. Czy coś takiego istnieje? Jeśli nie, to najbardziej pomocne byłoby rozwiązanie awk lub sed, ale moim pierwszym wyborem byłby komenda Linux.Łączenie wewnętrzne w dwóch plikach tekstowych

Oto przykład tego, co szukam zrobić

Plik 1:

0|Alien Registration Card LUA|Checklist Update 
1|Alien Registration Card LUA|Document App Plan 
2|Alien Registration Card LUA|SA Application Nbr 
3|Alien Registration Card LUA|tmp_preapp-DOB 
0|App - CSCE Certificate LUA|Admit Type 
1|App - CSCE Certificate LUA|Alias 1 
2|App - CSCE Certificate LUA|Alias 2 
3|App - CSCE Certificate LUA|Alias 3 
4|App - CSCE Certificate LUA|Alias 4 

Plik 2:

Alien Registration Card LUA 

Wyniki:

0|Alien Registration Card LUA|Checklist Update 
1|Alien Registration Card LUA|Document App Plan 
2|Alien Registration Card LUA|SA Application Nbr 
3|Alien Registration Card LUA|tmp_preapp-DOB 

Odpowiedz

5

nie powinno plik2 zawiera LUA na końcu?

Jeśli tak, można nadal korzystać join:

join -t'|' -12 <(sort -t'|' -k2 file1) file2 
+0

Dziękujemy! Tak, powinno (zaktualizowałem pytanie). Nie wiedziałem, że można wyłuskać i podać ten wynik z powrotem przez stdin. Całkiem użyteczne! –

+0

@DaveSnigier: Zawsze można utworzyć plik tymczasowy, ale podstawienie procesu jest znacznie krótsze. – choroba

0

Można użyć polecenia Wklej, aby połączyć plik:

paste [option] source files [>destination file] 

dla przykładu byłoby

paste file1.txt file2.txt >result.txt 
+0

Zamknij, ale wklejenie zostanie dołączone tylko do numerów linii dwóch plików.Właściwie to chcę zamiast tego dołączyć do pola w pliku. –

5

Ty może zmodyfikować ten skrypt:

cat file2 | while read line; do 
    grep $line file1 # or whatever you want to do with the $line variable 
done 

, podczas gdy pętla odczytuje plik2 linia po linii i podaje ten wiersz komendzie grep, która wyświetla ten wiersz w pliku1. Istnieje kilka dodatkowych wyników, które można usunąć za pomocą opcji grep.

+0

Bardzo sprytny! Będę w stanie znaleźć wiele zastosowań tego wzorca poza tym bezpośrednim problemem. –

+2

Nie zapomnij zacytować '$ line'. Jeśli zawiera spacje, może zostać źle rozszerzony. Ponadto, jeśli szukasz stałego dopasowywania ciągów zamiast wyrażeń regularnych (pamiętaj, że jest to GREp), użyj opcji '-F'. – ghoti

+2

To jest po prostu nieefektywna parafraza [this anwer] (http://stackoverflow.com/a/13278763/874188) autorstwa @glennjackman. (Tak, jego został opublikowany później.) Pojedynczy 'grep', który czyta we wzorcach, a następnie sprawdza plik docelowy tylko raz jest znacznie bardziej wydajny niż uruchomienie jednego' grep' dla każdego wzorca, szczególnie oczywiście dla dużych wejść. – tripleee

5

Oto opcja awk, dzięki czemu można uniknąć uzależnienia bash (do przenoszenia):

$ awk -F'|' 'NR==FNR{check[$0];next} $2 in check' file2 file1 

Jak to działa?

  • -F'|' - ustawia separator pól
  • 'NR==FNR{check[$0];next} - jeżeli łączna liczba rekord odpowiada rekordową liczbę plików (tj czytamy pierwszy plik na wyposażeniu), a następnie możemy zapełnić tablicę i kontynuować.
  • $2 in check - Jeśli drugie pole zostało wymienione w utworzonej macierzy, wydrukuj linię (która jest domyślną akcją, jeśli nie podano żadnych akcji).
  • file2 file1 - pliki. Zamówienie jest ważne ze względu na konstrukcję NR==FNR.
4

Wygląda wystarczy

grep -F -f file2 file1 
Powiązane problemy