Unisci i file usando una colonna comune


8

Ho due file da cui voglio creare un terzo che contiene tutte le informazioni.

file 1:

a 111 
b 222 
c 333 
d 666 
e 777 

file 2:

111 x1  
222 x2
333 x3
444 x4 
555 x5 
666 x6 
777 x7 
888 x8

Vorrei combinarli come segue:

111  x1  a
222  x2  b
333  x3  c
444  x4  0
555  x5  0
666  x6  d
777  x7  e
888  x8  0

Nota:

La seconda colonna del file 1 è un sottoinsieme della prima colonna del file 2

Risposte:


7

Il joincomando fa quasi quello che ti serve, se i file sono ordinati come nei tuoi esempi:

join -12 -a2 file1 file2 -o2.1,2.2,1.1

Hai solo bisogno di aggiungere gli zero alle linee senza corrispondenza. È possibile utilizzare l' -einterruttore per questo:

join -12 -a2 file1 file2  -o2.1,2.2,1.1 -e0

se aggiungi il -e0non necessario perl :)
LilloX

@LilloX: vero, grazie. Ho provato ma fallito (errore di battitura).
Choroba,

13

Utilizzando join:

join -1 1 -2 2 -a1 -e0 -o'0,1.2,2.1' file2 file1

Il comando join unisce le righe di due file che condividono un campo di dati comune. In questo caso: unire il file2 e il file1 utilizzando il campo 1 ( -1 1) del file2 e il campo 2 ( -2 2) del file1.

L'output sarà: "campo unito, campo 2 di file2, campo 1 di file1" ( -o'0,1.2,2.1'), se è presente un campo mancante inserire 0 ( -e0)

Se uno dei due file ha più record, aggiungili (in questo caso file2) ( -a1)

Fare riferimento alla manpage del comando join


Buona. Potresti aggiungere un po 'di spiegazione?
Lety,

Sicuro, aggiornato :)
LilloX

5

Un po 'di awkmagia:

awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0}; \
    printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}' \
    file1 file2

o

awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0};
    print $1,$2,a[$1]}' file1 file2

Produzione

111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0

Spiegazione

  • FNR==NR{a[$2]=$1;next}

    Riesce file1( FNR==NR) e crea una struttura valore-chiave. La chiave è la seconda colonna ( $2) di file1, il valore è la prima colonna ( $1) difile1

  • {if(a[$1]==""){a[$1]=0};print $1,$2,a[$1]}

    Funziona file2e

    • if(a[$1]==""){a[$1]=0}

      Se la chiave nella prima colonna ( $1) file2non esiste in file1, abbiamo bisogno di un0

    • print $1,$2,a[$1]

      Stampa (usando print) la prima e la seconda colonna di file2e il valore della struttura valore-chiave con la chiave della prima colonna ( $1) difile2

      o

    • printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}'

      Stampa (usando printf) la prima e la seconda colonna di file2e il valore della struttura valore-chiave con la chiave della prima colonna ( $1) di file2.

      • FS è il separatore tra le colonne, preso dal file di input

      • "%s%s%s%s%s\n"

        è la formattazione per l'output

        • %s - Corda

        • \n - Nuova linea


Potresti spiegare il codice?
gforce89,

Certo, risposta aggiornata.
AB

1

Utilizzando q :

$ q "select f2.c1, f2.c2, ifnull(f1.c1,0) from file_2.txt f2 LEFT JOIN file_1.txt f1 on f1.c2 = f2.c1 "
111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0

A volte può essere più leggibile in questo modo.


1
Per chiunque si chieda, qè nel pacchetto python3-q-text-as-data(Python 3) e nel pacchetto python-q-text-as-data(Python 2).
kos

Grazie, ma dove posso ottenere questo qpacchetto? Non mi sembra di essere in grado di installare uno python-q-text-as-datao python3-q-text-as-data. "E: Impossibile trovare il pacchetto python3-q-text-as-data". Il mio sistema è già installato python, python2.7, python3, e python3.4.
Paddy Landau,

Forse il pacchetto è troppo nuovo e non è disponibile nella versione di distribuzione. Puoi clonarlo Github: github.com/harelba/q
Vi.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.