GNU/Linux >> Linux Esercitazione >  >> Linux

Come unire due file usando AWK?

Per fortuna, non è affatto necessario scriverlo. Unix ha un comando join per farlo per te.

join -1 1 -2 1 File1 File2

Eccolo "in azione":

will-hartungs-computer:tmp will$ cat f1
4050 S00001 31228 3286 0
4050 S00012 31227 4251 0
4049 S00001 28342 3021 1
4048 S00001 46578 4210 0
4048 S00113 31221 4250 0
4047 S00122 31225 4249 0
4046 S00344 31322 4000 1
will-hartungs-computer:tmp will$ cat f2
4050 12.1 23.6
4049 14.4 47.8   
4048 23.2 43.9
4047 45.5 21.6
will-hartungs-computer:tmp will$ join -1 1 -2 1 f1 f2
4050 S00001 31228 3286 0 12.1 23.6
4050 S00012 31227 4251 0 12.1 23.6
4049 S00001 28342 3021 1 14.4 47.8
4048 S00001 46578 4210 0 23.2 43.9
4048 S00113 31221 4250 0 23.2 43.9
4047 S00122 31225 4249 0 45.5 21.6
will-hartungs-computer:tmp will$ 

$ awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' file2 file1
4050 S00001 31228 3286 0 12.1 23.6
4050 S00012 31227 4251 0 12.1 23.6
4049 S00001 28342 3021 1 14.4 47.8
4048 S00001 46578 4210 0 23.2 43.9
4048 S00113 31221 4250 0 23.2 43.9
4047 S00122 31225 4249 0 45.5 21.6
4046 S00344 31322 4000 1

Spiegazione:(In parte basata su un'altra domanda. Un po' in ritardo però.)

FNR si riferisce al numero di record (tipicamente il numero di riga) nel file corrente e NR si riferisce al numero totale di record. L'operatore ==è un operatore di confronto, che restituisce vero quando i due operandi circostanti sono uguali. Quindi FNR==NR{commands} significa che i comandi tra parentesi vengono eseguiti solo durante l'elaborazione del primo file (file2 adesso).

FS si riferisce al separatore di campo e $1 , $2 etc. sono i campi 1st, 2nd etc. in una riga. a[$1]=$2 FS $3 significa che un dizionario(/array) (denominato a ) viene riempito con $1 chiave e $2 FS $3 valore.

; separa i comandi

next significa che qualsiasi altro comando viene ignorato per la riga corrente. (L'elaborazione continua nella riga successiva.)

$0 è l'intera linea

{print $0, a[$1]} stampa semplicemente l'intera riga e il valore di a[$1] (se $1 è nel dizionario, altrimenti solo $0 viene stampato). Ora viene eseguito solo per il secondo file (file1 ora), a causa di FNR==NR{...;next} .


Devi leggere le voci dal File 2 in una coppia di array associativi nel blocco BEGIN. Supponendo che GNU Awk:

BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }

Nel blocco di elaborazione principale, leggi la riga dal File 1 e stampala con i dati corretti dagli array creati nel blocco BEGIN:

{ print $0, f[$1], g[$1] }

Fornisci File 1 come argomento del nome file al programma.

awk 'BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }
     print $0, f[$1], g[$1] }' "File 1"

Le virgolette attorno all'argomento del nome del file sono necessarie a causa degli spazi nel nome del file. Hai bisogno delle virgolette intorno al getline filename anche se non conteneva spazi poiché sarebbe altrimenti un nome di variabile.


Linux
  1. Come caricare file utilizzando File Manager in Cpanel

  2. Come creare file Proc Linux nel programma C usando LKM

  3. Come estraggo file senza struttura di cartelle usando tar

  4. Unisci manualmente due file usando diff

  5. Unisci due file HTML nel file HTML principale

Come eliminare le righe vuote nei file utilizzando Grep, Sed e Awk

Come confrontare i file in Linux usando lo strumento Meld (Diff/Merge).

Procedura:un'introduzione all'uso di Git

Trasferisci file usando WinSCP

Come proteggere con password i file usando l'editor Vim in Ubuntu

Come comprimere un file in Linux