Untungnya, Anda tidak perlu menulis ini sama sekali. Unix memiliki perintah bergabung untuk melakukan ini untuk Anda.
join -1 1 -2 1 File1 File2
Ini dia "beraksi":
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
Penjelasan:(Sebagian berdasarkan pertanyaan lain. Namun agak terlambat.)
FNR
mengacu pada nomor record (biasanya nomor baris) dalam file saat ini dan NR
mengacu pada jumlah total catatan. Operator ==adalah operator pembanding, yang mengembalikan true ketika dua operan di sekitarnya sama. Jadi FNR==NR{commands}
berarti perintah di dalam tanda kurung hanya dijalankan saat memproses file pertama (file2
sekarang).
FS
mengacu pada pemisah bidang dan $1
, $2
dll. adalah bidang 1, 2 dst. dalam satu baris. a[$1]=$2 FS $3
berarti kamus(/array) (bernama a
) diisi dengan $1
dan $2 FS $3
nilai.
;
memisahkan perintah
next
berarti bahwa perintah lain diabaikan untuk baris saat ini. (Pemrosesan berlanjut ke baris berikutnya.)
$0
adalah seluruh baris
{print $0, a[$1]}
cukup cetak seluruh baris dan nilai a[$1]
(jika $1
ada di kamus, selain itu hanya $0
dicetak). Sekarang hanya dieksekusi untuk file ke-2 (file1
sekarang), karena FNR==NR{...;next}
.
Anda perlu membaca entri dari File 2 ke dalam sepasang array asosiatif di blok BEGIN. Dengan asumsi GNU Awk:
BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }
Di blok pemrosesan utama, Anda membaca baris dari File 1 dan mencetaknya dengan data yang benar dari larik yang dibuat di blok BEGIN:
{ print $0, f[$1], g[$1] }
Berikan File 1 sebagai argumen nama file ke program.
awk 'BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }
print $0, f[$1], g[$1] }' "File 1"
Tanda kutip di sekitar argumen nama file diperlukan karena spasi dalam nama file. Anda memerlukan tanda kutip di sekitar getline
nama file meskipun tidak berisi spasi karena jika tidak, itu akan menjadi nama variabel.