2013-02-25 16 views
8

Ciao Ho due file simili (entrambi con 3 colonne). Vorrei verificare se questi due file contengono gli stessi elementi (ma elencati in ordini diversi). Prima di tutto mi piacerebbe confrontare solo il 1 ° colonneConfronta i file con awk

file1.txt

"aba" 0 0 
"abc" 0 1 
"abd" 1 1 
"xxx" 0 0 

file2.txt

"xyz" 0 0 
"aba" 0 0 
"xxx" 0 0 
"abc" 1 1 

Come posso farlo utilizzando awk? Ho provato a dare un'occhiata, ma ho trovato solo esempi complicati. Cosa succede se voglio includere anche le altre due colonne sul confronto? L'output dovrebbe darmi il numero di elementi corrispondenti.

+0

http://theunixshell.blogspot.in/2012/12/i-have-two-files-file-1-conta ins-3.html – Vijay

risposta

25

per stampare i comuni elementi in entrambi i file:

$ awk 'NR==FNR{a[$1];next}$1 in a{print $1}' file1 file2 
"aba" 
"abc" 
"xxx" 

Spiegazione:

NR e FNR sono awk variabili che memorizzano il numero totale di record e il numero di record nei file correnti rispettivamente (il record predefinito è una linea).

NR==FNR # Only true when in the first file 
{ 
    a[$1] # Build associative array on the first column of the file 
    next # Skip all proceeding blocks and process next line 
} 
($1 in a) # Check in the value in column one of the second files is in the array 
{ 
    # If so print it 
    print $1 
} 

Se si desidera far corrispondere l'intero linee quindi utilizzare $0:

$ awk 'NR==FNR{a[$0];next}$0 in a{print $0}' file1 file2 
"aba" 0 0 
"xxx" 0 0 

O un insieme specifico di colonne:

$ awk 'NR==FNR{a[$1,$2,$3];next}($1,$2,$3) in a{print $1,$2,$3}' file1 file2 
"aba" 0 0 
"xxx" 0 0 
+0

Votato specificamente a causa della spiegazione dello script awk, grazie! – vfilby

+0

@iiSeymour come stampare la seconda colonna di file1 se la prima colonna di file2 si trova nell'array associativo? –

6

Per stampare il numero di elementi corrispondenti, ecco uno modo utilizzando awk:

awk 'FNR==NR { a[$1]; next } $1 in a { c++ } END { print c }' file1.txt file2.txt 

risultati utilizzando il vostro input:

3 

Se vuoi aggiungere altre colonne (per esempio, le colonne di uno, due e tre), utilizzare un pseudo-multidimensional array:

awk 'FNR==NR { a[$1,$2,$3]; next } ($1,$2,$3) in a { c++ } END { print c }' file1.txt file2.txt 

Risultati utilizzando il tuo input:

2 
+0

+1. Dal momento che i file di OP hanno solo 3 colonne, potrebbe essere meglio usare semplicemente 'a [$ 0]' invece di 'a [$ 1, $ 2, $ 3]'. Tuttavia, qualsiasi spazio finale invisibile senza corrispondenza in entrambi i file può causare output imprevisti. Forse usa rtrim o gsub per quello. –

+1

Usato in questo modo -> za $ awk 'FNR == NR {a [$ 1]; next}! ($ 1 in a) END {print $ 1} 'test.csv test2.csv per stampare i record non corrispondenti. – zee

+0

@zee: Grazie per il voto, ma non è necessario il blocco 'END' – Steve