Uno script di shell per l'unione di due file


8

Voglio scrivere un shell scriptche ottiene due file Ae B, e ottenere un risultato come questo:

File A:

user_a tel_a addr_a
user_b tel_b addr_b

File B:

process_1 user_a
process_2 user_a
process_3 user_b

E il risultato:

user_a process_1 tel_a addr_a
user_a process_2 tel_a addr_a
user_b process_3 tel_b addr_b

Come posso fare questo? awko qualcos'altro?


2
Penso che possa essere fatto usando cute pastesolo, ma non riesco a trovare la sintassi giusta.
Bernhard,

I miei file hanno molti record e campi, non riesco a tagliare e incollare !! Questo è solo un esempio.
Navid Farhadi,

1
@NavidFarhadi non taglia e incolla: ci sono due comandi reali cute pasteguarda la loro pagina di manuale.
Matteo,

Posso caricare completamente entrambi i file in memoria e posso anche usare awk.
Navid Farhadi,

Posso anche usare perl o altri, se fossero eseguibili nella riga di comando di Linux.
Navid Farhadi,

Risposte:


15

join ...

join -1 2 -2 1 FileB FileA

Produzione

user_a process_1 tel_a addr_a
user_a process_2 tel_a addr_a
user_b process_3 tel_b addr_b

I file di input devono essere ordinati in base al campo chiave ... I file di esempio sono già ordinati, quindi non è necessario, ma in caso contrario è possibile incorporare l'ordinamento come segue.

join -1 2 -2 1 <(sort -k2 FileB) <(sort FileA)

Cosa significano i parametri numerici?
Navid Farhadi,

5
@Navid: si può sempre ottenere la migliore e più accurata descrizione della paramaters di un comando facendo riferimento al manuale di , digitando man joinnella riga di comando del terminale ... -1 2   -2 1 significa: unire il '1 ° 2 ° file-campo' e il ' 2 ° file 1 ° campo '
Peter.O

3

Poiché joine pastenon sono disponibili ovunque (non sono sul mio sistema basato su BusyBox, ad esempio), ecco come farlo con awk, come richiesto:

awk 'BEGIN {
    while( (getline < "fileA") > 0) A[$1]=$2 OFS $3 # read fileA into the array A
    close("fileA")
  } {
    print $2, $1, A[$2]
  }' fileB

A proposito, ti sei perso il separatore A[$1]=$2 OFS $3... Ecco un'altra variante che evita il loop manuale in INIZIA, ma è praticamente lo stesso (da awk ), anche se introduce un test di condizione altrimenti non necessario per il secondo file: awk 'NR==FNR {A[$1]=$2 OFS $3;next} {print $2, $1, A[$2]}' fileA fileB... (+ 1)
Peter,
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.