Peralatan section ini bekerja pada isi file — tetapi pertanyaan sehari-hari sering mendahuluinya: file yang mana? File log mana yang lebih besar dari satu megabyte, file sumber mana saja yang berakhiran .c, berkas mana yang berubah sejak kemarin. Perintah find menjawab dengan menelusuri direktori dan mencocokkan atribut tiap temuan: nama, tipe, ukuran, waktu. Sahabat karibnya xargs mengubah daftar hasil itu menjadi argumen perintah lain, sehingga ribuan file bisa diproses sekaligus. Pada chapter ini kita bangun folder latihan, menyaringnya dengan berbagai kriteria, menindaklanjuti temuan lewat -exec, lalu menutup dengan pola find | xargs — termasuk perangkap klasiknya: nama file yang mengandung spasi.

Menemukan File berdasar Nama dan Tipe #

Struktur dasarnya find direktori kriteria: telusuri direktori beserta seluruh isinya secara rekursif, lalu cetak path yang lolos semua kriteria. Kriteria yang paling sering dipakai: -name mencocokkan nama (peka huruf besar-kecil), -type f hanya file biasa, -type d hanya direktori, dan -maxdepth membatasi kedalaman penelusuran:

bash
mkdir -p proyek/src proyek/docs
printf 'int main() { return 0; }\n' > proyek/src/main.c
printf 'int util() { return 1; }\n' > proyek/src/util.c
printf 'catatan penting\n' > proyek/docs/catatan.txt
printf 'arsip lama\n' > 'proyek/berkas lama.txt'
find proyek -name '*.c' | sort
find proyek -type d | sort
find proyek -maxdepth 1 -type f | sort

Output yang Dihasilkan:

text
proyek/src/main.c
proyek/src/util.c
proyek
proyek/docs
proyek/src
proyek/berkas lama.txt

Mari kita bedah baris per barisnya:

  1. Baris 1-5: membangun folder proyek berisi dua file .c di src/, satu .txt di docs/, dan satu file yang sengaja dinamai dengan spasi — file itu akan penting di bagian penutup pembahasan find.
  2. Baris 6 (find proyek -name '*.c' | sort): hanya path berakhiran .c yang lolos; pipe ke sort sekadar menjaga urutan tampilan.
  3. Baris 7 (find proyek -type d | sort): tiga direktori — proyek sendiri beserta dua anaknya.
  4. Baris 8 (find proyek -maxdepth 1 -type f | sort): hanya file tepat satu tingkat di bawah proyek; file di dalam src dan docs terlalu dalam sehingga tersaring.

Menyaring berdasar Ukuran dan Waktu #

find tidak berhenti di nama. Kriteria -size membandingkan ukuran: +1k berarti lebih dari satu kibibyte, -1k berarti kurang dari itu, dan satuannya bisa c (byte), k, M, atau G. Kriteria waktu membandingkan mtime — waktu modifikasi terakhir: -newer file lolos bila file diubah lebih baru dari file pembanding:

bash
mkdir -p unduhan log
seq 1 1000 > unduhan/besar.txt
printf 'hanya sebaris\n' > unduhan/kecil.txt
find unduhan -type f -size +1k
find unduhan -type f -size -1k
printf 'x\n' > log/lama.log
printf 'y\n' > log/baru.log
touch -d '2026-01-10 08:00' log/lama.log
touch -d '2026-01-15 08:00' log/baru.log
find log -type f -newer log/lama.log
find log -type f -newermt '2026-01-12'

Output yang Dihasilkan:

text
unduhan/besar.txt
log/baru.log
log/baru.log

Mari kita bedah baris per barisnya:

  1. Baris 2-3: seq 1 1000 menghasilkan file sekitar 4 KB; file sebaris hanya belasan byte.
  2. Baris 4-5 (-size): tanda plus berarti lebih besar dari, tanda minus berarti lebih kecil dari — besar.txt dan kecil.txt berpisah rapi.
  3. Baris 6-9: touch -d menetapkan tanggal tetap pada kedua file log agar contoh ini bisa diulang dengan hasil sama; di dunia nyata mtime terisi otomatis setiap kali file ditulis.
  4. Baris 10 (-newer log/lama.log): hanya baru.log yang waktunya setelah lama.log.
  5. Baris 11 (-newermt '2026-01-12'): membandingkan langsung dengan tanggal — 12 Januari 2026 — tanpa perlu file pembanding.

Kerabat waktu yang lain: -mtime -1 berarti diubah dalam 24 jam terakhir, dan -mmin -30 berarti dalam 30 menit terakhir. Kombinasi klasiknya find /var/log -name '*.log' -mtime +7 — file log yang tak tersentuh lebih dari sehari seminggu — kandidat utama untuk diarsipkan atau dihapus.

Menindaklanjuti Temuan dengan -exec #

Menemukan file baru setengah pekerjaan; find juga bisa langsung menjalankan perintah pada tiap temuan lewat -exec. Placeholder {} diganti path temuan, dan akhiran eksekusinya dua pilihan: \; menjalankan perintah sekali per file, sedangkan + mengemas semua temuan menjadi satu panggilan — jauh lebih hemat proses. Kriteria -delete menghapus temuan tanpa bertanya:

bash
mkdir -p proyek/src proyek/docs
printf 'int main() { return 0; }\n' > proyek/src/main.c
printf 'int util() { return 1; }\n' > proyek/src/util.c
printf 'catatan penting\n' > proyek/docs/catatan.txt
printf 'file sementara\n' > proyek/lama.bak
find proyek -name '*.bak' -delete
find proyek -name '*.bak' | wc -l
find proyek -name '*.c' -exec grep -n return {} + | sort
find proyek -name 'main.c' -exec grep -c int {} \;

Output yang Dihasilkan:

text
0
proyek/src/main.c:1:int main() { return 0; }
proyek/src/util.c:1:int util() { return 1; }
1

Mari kita bedah baris per barisnya:

  1. Baris 5 (find proyek -name '*.bak' -delete): menghapus lama.bak seketika — tanpa output dan tanpa konfirmasi.
  2. Baris 6 (find proyek -name '*.bak' | wc -l): wc -l dari chapter sebelumnya memverifikasi tidak ada .bak tersisa — hasilnya 0.
  3. Baris 7 (-exec grep -n return {} +): kedua file .c diserahkan ke satu proses grep, yang mencetak temuan lengkap dengan prefiks nama file.
  4. Baris 8 (-exec grep -c int {} \;): bentuk per-file — grep dijalankan khusus untuk main.c saja; pilih bentuk ini bila perintah target hanya masuk akal dipanggil satu per satu.

xargs: Dari Daftar ke Argumen #

find mencetak path ke stdout — sementara banyak perintah ingin menerima path sebagai argumen, bukan baris stdin. Di sinilah xargs menjejembatani: membaca stdin, memecahnya menjadi kata-kata, lalu menempelkan kata-kata itu sebagai argumen di akhir perintah target. Mekanisme pemecahan pada spasi inilah yang menyimpan masalah:

bash
mkdir -p arsip
printf 'satu\n' > arsip/a.txt
printf 'dua\n' > arsip/b.txt
printf 'tiga\n' > 'arsip/c berkas.txt'
find arsip -name '*.txt' | sort | xargs ls -1 2>&1

Output yang Dihasilkan:

text
ls: cannot access 'arsip/c': No such file or directory
ls: cannot access 'berkas.txt': No such file or directory
arsip/a.txt
arsip/b.txt

Baris arsip/c berkas.txt terbelah menjadi dua kata oleh xargs, sehingga ls menerima argumen arsip/c dan berkas.txt yang tidak ada — dua baris error di awal keluaran, dan exit code 123 menandakan sebagian pemanggilan gagal. Dua file lain tetap tercetak, itulah yang membuat kesalahan semacam ini mudah luput.

Solusinya: -print0, xargs -0, dan -I #

Opsi -print0 mengubah pemisah antar path menjadi karakter NOL, dan xargs -0 membaca pemisah itu — nama file seaneh apa pun terkirim utuh. Opsi -I{} menjalankan perintah sekali per item dengan {} sebagai tempat peletakan argumen, bukan hanya di baris akhir:

bash
mkdir -p arsip cadangan
printf 'satu\n' > arsip/a.txt
printf 'dua\n' > arsip/b.txt
printf 'tiga\n' > 'arsip/c berkas.txt'
find arsip -name '*.txt' -print0 | xargs -0 ls -1
find arsip -name '*.txt' -print0 | xargs -0 -I{} mv {} cadangan/
ls cadangan

Output yang Dihasilkan:

text
arsip/a.txt
arsip/b.txt
arsip/c berkas.txt
a.txt
b.txt
c berkas.txt

Mari kita bedah baris per barisnya:

  1. Baris 5 (... -print0 | xargs -0 ls -1): ketiga path kini diterima ls dalam keadaan utuh — termasuk arsip/c berkas.txt yang tadi gagal.
  2. Baris 6 (xargs -0 -I{} mv {} cadangan/): satu mv per file; tiap pemanggilan menerima satu path pada posisi {}.
  3. Baris 7 (ls cadangan): memastikan ketiga file benar-benar pindah.

Opsi -n N membatasi jumlah argumen per pemanggilan — misalnya xargs -n 2 — berguna bila perintah target hanya sanggup mencerna beberapa argumen sekaligus. Bandingkan pula dengan -exec: find -exec perintah {} + memanggil perintah langsung tanpa proses perantara, sedangkan find | xargs memberi kita kesempatan menyisipkan sort, head, atau filter lain sebelum argumen sampai ke perintah target.

Dengan find dan xargs, kita bisa memilih file lalu langsung mengolahnya dengan grep, wc, atau perintah apa pun. Satu format data modern masih sulit digarap alat baris-teks klasik: JSON yang bersarang — dan untuk itulah jq ada, chapter penutup section ini. Detail lengkapnya tersedia di halaman manual find(1) dan xargs(1) .