Perintah join Linux: gabungkan berkas lewat field kunci

Perintah join menggabungkan baris dari dua berkas teks ketika nilai field kuncinya sama. Secara bawaan, kunci berada pada field pertama, kedua masukan harus diurutkan menurut kunci itu, dan hanya pasangan yang cocok yang ditampilkan. Untuk memeriksa baris tanpa pasangan, gunakan opsi -a atau -v sesuai hasil yang diperlukan.

Field adalah bagian baris yang dipisahkan menurut aturan masukan; kunci adalah field yang dibandingkan untuk menghubungkan record. Berbeda dari perintah paste yang menyandingkan posisi baris, join mencari kesamaan nilai kunci. Karena itu, pilihan kunci dan urutan perbandingan harus konsisten pada kedua berkas.

Sintaks dasar

join [OPSI]... BERKAS1 BERKAS2

BERKAS1 dan BERKAS2 adalah dua masukan, sedangkan OPSI merupakan penanda opsi yang perlu disesuaikan. Tanpa -t, field dipisahkan oleh deretan spasi putih seperti spasi atau tab, dan spasi awal diabaikan. Secara bawaan, keluaran berisi kunci, field lain dari berkas pertama, lalu field lain dari berkas kedua, dengan spasi sebagai pemisah.

Contoh ini memakai GNU join dan opsi GNU --check-order. Periksa join --version, join --help, dan man join pada sistem Anda karena implementasi dan opsi dapat berbeda.

Siapkan data, urutkan, lalu periksa hasil

Jalankan seluruh blok berikut di Bash atau shell yang mendukung sintaksnya. Blok membuat direktori latihan baru dengan mktemp, menyiapkan setiap berkas yang diperlukan di dalamnya, lalu menampilkan lokasinya pada baris terakhir. Tanda kurung membuat subshell, sehingga direktori kerja terminal Anda kembali seperti semula setelah blok selesai. Nama berkas dalam direktori kerja semula tidak ditimpa.

(
set -eu
labdir=$(mktemp -d)
cd "$labdir"
printf 'b Bob
a Ana
c Cat
' > names.txt
printf 'a 7
b 12
' > scores.txt
LC_ALL=C sort -k1,1 names.txt > names.sorted
LC_ALL=C sort -k1,1 scores.txt > scores.sorted
LC_ALL=C join --check-order names.sorted scores.sorted
LC_ALL=C join --check-order -a 1 names.sorted scores.sorted
printf 'a:Ana
b:Bob
' > users.txt
printf 'a:reader
b:writer
' > roles.txt
LC_ALL=C sort -t ':' -k1,1 users.txt > users.sorted
LC_ALL=C sort -t ':' -k1,1 roles.txt > roles.sorted
LC_ALL=C join --check-order -t ':' users.sorted roles.sorted
printf 'Lab files: %s\n' "$labdir"
)

Keluaran terdiri dari tiga kelompok hasil berikut, disusul baris Lab files: yang menunjukkan lokasi direktori latihan:

  1. Join pertama menghasilkan a Ana 7 dan b Bob 12. Kunci c hanya ada pada names.sorted sehingga tidak masuk hasil bawaan.
  2. Join dengan -a 1 menghasilkan dua pasangan tadi dan c Cat. Baris Cat dipertahankan tanpa skor karena tidak mempunyai pasangan di berkas kedua.
  3. Contoh berpemisah titik dua menghasilkan a:Ana:reader dan b:Bob:writer. Sort dan join sama-sama memakai -t ':' agar field kuncinya sesuai.

Kunci dibandingkan sebagai teks. Kedua tahap sort dan join memakai LC_ALL=C untuk aturan perbandingan berbasis bita yang konsisten pada data latihan. Locale C membantu reproduksibilitas, tetapi bukan urutan kamus alami untuk semua bahasa. Panduan sort menjelaskan pemilihan field dan pengaruh locale.

Opsi --check-order memeriksa urutan masukan, termasuk ketika semua baris dapat dipasangkan. Jika perintah gagal, jangan gunakan keluaran parsialnya sebagai hasil lengkap. set -eu pada subshell menghentikan blok ketika salah satu perintah utama gagal. Periksa pesan kesalahan dan hasilnya sebelum melanjutkan.

Pilih baris tanpa pasangan dan bentuk keluaran

Untuk mencoba perintah lanjutan di bagian ini, pindah terlebih dahulu ke direktori latihan yang dicetak setelah teks Lab files:. Misalnya, ganti penanda jalur dalam cd "/jalur/latihan-yang-dicetak" dengan lokasi yang benar. Berkas names.sorted dan scores.sorted dari blok sebelumnya tetap tersedia di sana sampai Anda membersihkannya.

Bedakan -a dan -v

LC_ALL=C join --check-order -v 1 names.sorted scores.sorted menghasilkan hanya c Cat. Opsi -v 1 memilih baris berkas pertama yang tidak mempunyai pasangan dan menyembunyikan pasangan yang cocok. Sebaliknya, -a 1 menambahkan baris tanpa pasangan itu ke hasil pasangan normal.

Angka 1 atau 2 pada -a dan -v menunjuk berkas masukan, bukan nomor field. Gunakan -a 2 untuk menyertakan baris tanpa pasangan dari berkas kedua, atau -v 2 untuk menampilkan hanya baris tanpa pasangan dari berkas kedua. Pada data latihan ini, setiap kunci scores.sorted memiliki pasangan, sehingga -v 2 tidak menghasilkan baris.

Tentukan kolom dan isi field yang hilang

Untuk menampilkan kunci, nama, dan skor pada kolom yang tetap, coba LC_ALL=C join --check-order -a 1 -e NA -o 0,1.2,2.2 names.sorted scores.sorted. Hasilnya a Ana 7, b Bob 12, dan c Cat NA. Penanda NA berarti field skor tidak tersedia pada contoh ini, bukan nilai skor nol.

Pada format -o, 0 berarti field kunci gabungan, 1.2 berarti field kedua dari masukan pertama, dan 2.2 berarti field kedua dari masukan kedua. Opsi -e memberi pengganti untuk field kosong atau hilang yang diminta. Menentukan -o secara eksplisit membantu menjaga bentuk hasil ketika baris tanpa pasangan ikut ditampilkan.

Opsi yang penting

Opsi Kegunaan
-t KARAKTER Tentukan karakter pemisah field masukan dan keluaran.
-1 N / -2 N Pilih field kunci masukan pertama dan kedua; penomoran field dimulai dari 1.
-a 1 / -a 2 Sertakan juga baris tanpa pasangan dari masukan yang ditentukan.
-v 1 / -v 2 Tampilkan hanya baris tanpa pasangan dari masukan yang ditentukan.
-o FORMAT Tentukan field dan urutan kolom keluaran.
-e TEKS Isi field kosong atau hilang yang diminta dengan teks pengganti.
--check-order Periksa urutan masukan dan laporkan kegagalan jika tidak sesuai.

Jika kunci berkas pertama berada pada field kedua dan kunci berkas kedua pada field pertama, gunakan -1 2 -2 1, lalu urutkan masing-masing masukan menurut field yang sesuai. Jangan hanya mengganti opsi join sementara salinan masukan masih diurutkan menurut field lain.

Hal yang perlu diperhatikan

Samakan aturan pengurutan dan perbandingan kunci

Gunakan kunci, pemisah, dan locale yang sama pada tahap pengurutan dan penggabungan. Data latihan tidak mempunyai spasi awal pada kunci. Untuk mode bawaan join yang mengabaikan spasi awal, GNU mendokumentasikan bentuk sort -k1b,1 agar pemilihan kunci sort selaras. Jika memakai pemisah khusus seperti titik dua, gunakan -t yang sesuai pada sort dan join.

Join membandingkan kunci sebagai teks, bukan otomatis sebagai angka. Dalam locale C, kunci 10 mendahului 2 pada urutan teks. Jangan menyortir kunci dengan -n lalu menganggap hasilnya pasti memenuhi urutan perbandingan join. Perlakukan nomor identitas sebagai teks kecuali Anda memang menormalisasi formatnya dengan aturan yang jelas.

Kunci berulang dapat menghasilkan banyak pasangan

Jika kunci a mempunyai dua baris pada masukan pertama dan tiga baris pada masukan kedua, join dapat menghasilkan enam pasangan untuk kunci tersebut. Hasilnya mencakup setiap kombinasi baris yang cocok, bukan memilih satu pasangan secara otomatis. Periksa keunikan kunci dan jumlah baris hasil jika kebutuhan Anda adalah hubungan satu banding satu.

Simpan hasil terpisah dan periksa sebelum digunakan

Di direktori latihan, LC_ALL=C join --check-order names.sorted scores.sorted > joined.txt menyimpan hasil ke berkas baru. Pengalihan > menimpa tujuan yang sudah ada; jangan arahkan ke salah satu berkas masukan. Jika join gagal, joined.txt mungkin sudah berisi keluaran parsial, sehingga keberadaan berkas saja bukan bukti bahwa proses berhasil.

Periksa status perintah, baris yang tidak cocok, dan jumlah pasangan sebelum memakai hasil untuk analisis. Direktori latihan tetap disimpan agar hasil dapat diperiksa. Setelah selesai, bersihkan hanya direktori latihan yang lokasinya telah Anda pastikan, bukan direktori kerja atau data asli.

FAQ

Bisakah dua berkas langsung digabungkan tanpa diurutkan?

Untuk penggunaan biasa, kedua masukan harus diurutkan menurut field kunci dengan aturan yang sesuai dengan join. Buat salinan terurut dengan locale dan pemisah yang sama, lalu gunakan --check-order jika tersedia. Masukan yang kebetulan menghasilkan sebagian pasangan belum membuktikan urutannya benar.

Dokumentasi

Definisi opsi, urutan kunci, dan format keluaran tersedia pada manual GNU join dari proyek Coreutils, ditayangkan di man7.