2012-11-07 10 views
5

Cercare di eseguire un join interno su due file di testo diversi. Fondamentalmente sto cercando l'equivalente inner join del programma di join di GNU. Esiste una cosa del genere? In caso contrario, una soluzione awk o sed sarebbe molto utile, ma la mia prima scelta sarebbe un comando Linux.Join interno su due file di testo

Ecco un esempio di quello che sto cercando di fare

File 1: File

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 

2:

Alien Registration Card LUA 

Risultati:

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 

risposta

5

Non dovrebbe il file2 contiene LUA alla fine?

Se sì, è ancora possibile utilizzare join:

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

Grazie! Sì, dovrebbe (ho aggiornato la domanda). Non sapevo che si può sborsare e alimentare quel risultato di nuovo attraverso stdin. Abbastanza utile! –

+0

@DaveSnigier: è sempre possibile creare un file temporaneo, ma Process Substitution è molto più breve da digitare. – choroba

0

È possibile utilizzare il comando paste per combinare file di:

paste [option] source files [>destination file] 

per il tuo esempio sarebbe

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

Chiudi, ma incollerà solo i numeri di riga di due file.In realtà sto cercando di unirmi su un campo nel file. –

5

È può modificare questo script:

while loop legge file2 riga per riga e da tale riga al comando grep che esegue il grep di quella riga nel file1. Ci sono alcuni extra che potrebbero essere rimossi con le opzioni di grep.

+0

Molto intelligente! Sarò in grado di trovare molti usi per questo modello al di là di questo problema immediato –

+2

Non dimenticare di citare '$ line'. Se contiene spazi, potrebbe essere ampliato male. Inoltre, se stai cercando la corrispondenza delle stringhe fisse piuttosto che le espressioni regolari (ricorda, è gREp), quindi usa l'opzione '-F'. – ghoti

+2

Questa è solo una parafrasi inefficiente di [this anwer] (http://stackoverflow.com/a/13278763/874188) di @glennjackman. (Sì, il suo è stato pubblicato più tardi.) Un singolo 'grep' che legge i pattern e poi controlla il file di destinazione una sola volta è molto più efficiente di eseguire un' grep' per ciascun pattern, specialmente per gli input di grandi dimensioni. – tripleee

5

Ecco un'opzione awk, in modo da poter evitare la dipendenza bash (per la portabilità):

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

Come funziona?

  • -F'|' - imposta il separatore di campo
  • 'NR==FNR{check[$0];next} - se il numero totale di registrazione corrisponde al numero di record del file (vale a dire che stiamo leggendo il primo file fornito), poi abbiamo compilare una matrice e continuare.
  • $2 in check - Se il secondo campo è stato menzionato nell'array creato, stampare la riga (che è l'azione predefinita se non vengono fornite azioni).
  • file2 file1 - i file. L'ordine è importante a causa del costrutto NR==FNR.
4

Sembra basta

grep -F -f file2 file1 
Problemi correlati