2015-06-05 15 views
5

Ho sotto lo script per combinare due file.Linux awk unire due file

awk -F"\t" ' 
    {key = $1} 
    !(key in result) {result[key] = $0; next;} 
    { for (i=2; i <= NF; i++) result[key] = result[key] FS $i } 
    END { 
     PROCINFO["sorted_in"] = "@ind_str_asc" # if using GNU awk 
     for (key in result) print result[key] 
    } 
' $1 $2 > $3 

La prima colonna è la chiave e sia $ 1 sia $ 2. Ma se la colonna $ 2 ha una chiave ma la colonna $ 1 non ha la chiave.

quindi si combina tranne $ 1 riga.

Voglio combinare solo in $ 1 chiave esiste. Come posso semplicemente combinare questi due file?

Per esempio,

File 1

Key Column1 Column2 Column3 
Test1 500  400  200    
Test2 499  400  200    
Test5 600  200  150    
Test6 600  199  150    
Test7 599  199  100    

File2

Key Column4 Column5 
Test1 Good  Good      
Test2 Good  Good 
Test3 Good  Good      
Test4 Good  Good 
Test5 Good  Good      
Test6 Good  Good 
Test7 Good  Good 

attuale Combine

Key Column1 Column2 Column3 Column4 Column5 
Test1 500  400  200  Good  Good  
Test2 499  400  200  Good  Good  
Test5 600  200  150  Good  Good   
Test6 600  199  150  Good  Good   
Test7 599  199  100  Good  Good 
Test3 Good Good 
Test4 Good Good 

Previsto Combine.

Key Column1 Column2 Column3 Column4 Column5 
Test1 500  400  200  Good  Good  
Test2 499  400  200  Good  Good  
Test5 600  200  150  Good  Good   
Test6 600  199  150  Good  Good   
Test7 599  199  100  Good  Good 

Grazie!

+0

Le frasi 'prima colonna è chiave e sia $ 1 e $ 2. Ma se la colonna $ 2 ha una chiave ma la colonna $ 1 non ha la chiave. poi anche si combina tranne $ 1 row. non significa niente. Dovresti cambiarli per riflettere ciò che intendi o semplicemente cancellarli. –

risposta

7

Stai andando su questo torto. Quello che si sta descrivendo è un'operazione join e c'è una perfetta buon strumento di UNIX per questo con un nome molto evidente:

$ join file1 file2 | column -t 
Key Column1 Column2 Column3 Column4 Column5 
Test1 500  400  200  Good  Good 
Test2 499  400  200  Good  Good 
Test5 600  200  150  Good  Good 
Test6 600  199  150  Good  Good 
Test7 599  199  100  Good  Good 

o se ti ostini a awk:

$ awk 'NR==FNR{m[$1]=$2" "$3; next} {print $0, m[$1]}' file2 file1 | column -t 
Key Column1 Column2 Column3 Column4 Column5 
Test1 500  400  200  Good  Good 
Test2 499  400  200  Good  Good 
Test5 600  200  150  Good  Good 
Test6 600  199  150  Good  Good 
Test7 599  199  100  Good  Good 
+0

Grazie a te sta funzionando –

4

aggiungere una condizione in cui la memorizzazione nella matrice

{key = $1} 
!(key in result) && NR == FNR {result[key] = $0; next;} 
(key in result) { for (i=2; i <= NF; i++) { 
    result[key] = result[key] FS $i 
    } 
} 
END { 
    PROCINFO["sorted_in"] = "@ind_str_asc" # if using GNU awk 
    for (key in result) print result[key] 
} 

Il NR == FNR fa in modo che il key memorizziamo in result è dal 1 ° file. Aggiungiamo anche (key in result) per assicurarci che la chiave esista prima di iterare attraverso il ciclo for.

4

Si può provare seguente comando:

awk ' 
    BEGIN { FS = OFS = "\t" } 
    {key = $1} 
    FNR == NR {result[key] = $0; next;} 
    (key in result) { for (i=2; i <= NF; i++) result[key] = result[key] FS $i } 
    END { 
     PROCINFO["sorted_in"] = "@ind_str_asc" # if using GNU awk 
     for (key in result) print result[key] 
    } 
' file1 file2 

ho cambiato tali controlli. Lo FNR == NR salva solo nelle righe result dal primo file. E (key in result) si applica per il secondo file e aggiunge solo le colonne per quelle chiavi trovate precedentemente nel primo file.

Produce:

Key  Column1 Column2 Column3   Column4 Column5 
Test1 500  400  200    Good Good 
Test2 499  400  200    Good Good 
Test5 600  200  150    Good Good 
Test6 600  199  150    Good Good 
Test7 599  199  100    Good Good 
+0

Grazie per la risposta anche questo funziona :) –