Cara Melintasi Pohon Direktori di Linux

Diterbitkan: 2022-07-21
Laptop Linux menampilkan prompt bash
fatmawati achmad zaenuri/Shutterstock.com

Direktori di Linux memungkinkan Anda mengelompokkan file dalam koleksi yang berbeda dan terpisah. Kelemahannya adalah berpindah dari direktori ke direktori menjadi membosankan untuk melakukan tugas yang berulang. Berikut cara mengotomatiskannya.

Semua Tentang Direktori

Perintah pertama yang Anda pelajari ketika Anda diperkenalkan ke Linux mungkin adalah ls , tetapi cd tidak akan jauh di belakangnya. Memahami direktori dan cara memindahkannya, khususnya subdirektori bersarang, adalah bagian mendasar dari pemahaman bagaimana Linux mengatur dirinya sendiri, dan bagaimana Anda dapat mengatur pekerjaan Anda sendiri ke dalam file, direktori, dan subdirektori.

Struktur Direktori Linux, Dijelaskan
TERKAIT Struktur Direktori Linux, Dijelaskan

Memahami konsep pohon direktori—dan cara berpindah di antara mereka—adalah salah satu dari banyak pencapaian kecil yang Anda lewati saat Anda membiasakan diri dengan lanskap Linux. Menggunakan cd dengan jalur membawa Anda ke direktori itu. Pintasan seperti cd ~ atau cd sendiri membawa Anda kembali ke direktori home Anda, dan cd .. memindahkan Anda satu tingkat di pohon direktori. Sederhana.

Namun, tidak ada cara yang sama sederhananya untuk menjalankan perintah di semua direktori dari pohon direktori. Ada berbagai cara kita dapat mencapai fungsionalitas itu, tetapi tidak ada perintah Linux standar yang didedikasikan untuk tujuan itu.

Beberapa perintah, seperti ls , memiliki opsi baris perintah yang memaksanya untuk beroperasi secara rekursif , artinya perintah tersebut dimulai dalam satu direktori dan secara metodis bekerja melalui seluruh pohon direktori di bawah direktori tersebut. Untuk ls , ini adalah opsi -R (rekursif).

Jika Anda perlu menggunakan perintah yang tidak mendukung rekursi, Anda harus menyediakan sendiri fungsi rekursif tersebut. Berikut cara melakukannya.

TERKAIT: 37 Perintah Linux Penting Yang Harus Anda Ketahui

Komando pohon

Perintah tree tidak akan membantu kita dengan tugas yang ada, tetapi membuatnya mudah untuk melihat struktur pohon direktori. Itu menggambar pohon di jendela terminal sehingga kita bisa mendapatkan gambaran instan tentang direktori dan subdirektori yang membentuk pohon direktori, dan posisi relatifnya di pohon.

Anda harus menginstal tree .

Di Ubuntu Anda perlu mengetik:

 sudo apt install tree 

Menginstal pohon di Ubuntu

Di Fedora, gunakan:

 sudo dnf instal pohon 

Memasang pohon di Fedora

Di Manjaro, perintahnya adalah:

 sudo pacman -pohon sy 

Memasang pohon di Manjaro

Menggunakan tree tanpa parameter menarik keluar pohon di bawah direktori saat ini.

 pohon 

Menjalankan pohon di direktori saat ini

Anda dapat melewati jalur ke tree di baris perintah.

 pekerjaan pohon 

Menjalankan pohon pada direktori tertentu

Opsi -d (direktori) mengecualikan file dan hanya menampilkan direktori.

 pohon -d kerja 

Menjalankan pohon dan hanya menampilkan direktori

Ini adalah cara paling mudah untuk mendapatkan pandangan yang jelas tentang struktur pohon direktori. Pohon direktori yang ditampilkan di sini adalah yang digunakan dalam contoh berikut. Ada lima file teks dan delapan direktori.

Jangan Parsing Output Dari ls ke Traverse Directories

Pikiran pertama Anda mungkin, jika ls dapat secara rekursif melintasi pohon direktori, mengapa tidak menggunakan ls untuk melakukan hal itu dan menyalurkan output ke beberapa perintah lain yang mengurai direktori dan melakukan beberapa tindakan?

Parsing output dari ls dianggap praktik yang buruk. Karena kemampuan di Linux untuk membuat nama file dan direktori yang berisi semua jenis karakter aneh, menjadi sangat sulit untuk membuat parser generik yang benar secara universal.

Anda mungkin tidak pernah secara sadar membuat nama direktori yang tidak masuk akal seperti ini, tetapi kesalahan dalam skrip atau aplikasi mungkin terjadi.

Nama direktori yang aneh

Mengurai nama file dan direktori yang sah tetapi tidak dipertimbangkan dengan baik adalah rawan kesalahan. Ada metode lain yang dapat kita gunakan yang lebih aman dan lebih kuat daripada mengandalkan interpretasi keluaran ls .

Menggunakan perintah find

Perintah find memiliki kemampuan rekursif bawaan, dan juga memiliki kemampuan untuk menjalankan perintah untuk kita. Ini memungkinkan kita membangun one-liners yang kuat. Jika itu adalah sesuatu yang mungkin ingin Anda gunakan di masa mendatang, Anda dapat mengubah one-liner Anda menjadi alias atau fungsi shell.

Perintah ini secara rekursif mengulang melalui pohon direktori, mencari direktori. Setiap kali menemukan direktori, ia mencetak nama direktori dan mengulangi pencarian di dalam direktori itu. Setelah selesai mencari satu direktori, ia keluar dari direktori itu dan melanjutkan pencarian di direktori induknya.

 cari pekerjaan -type d -execdir echo "In:" {} \; 

menggunakan perintah find untuk menemukan direktori secara rekursif

Anda dapat melihat berdasarkan urutan daftar direktori, bagaimana pencarian berlangsung melalui pohon. Dengan membandingkan output dari perintah tree dengan output dari find one-liner, Anda akan melihat bagaimana find mencari setiap direktori dan subdirektori secara bergantian hingga mencapai direktori tanpa subdirektori. Kemudian kembali naik satu tingkat dan melanjutkan pencarian di tingkat itu.

Begini cara perintah dibuat.

  • find : Perintah find .
  • work : Direktori untuk memulai pencarian. Ini bisa berupa path.
  • -type d : Kami sedang mencari direktori.
  • -execdir : Kita akan menjalankan perintah di setiap direktori yang kita temukan.
  • echo “In:” {} : Ini adalah perintahnya., Kami hanya mengulang nama direktori ke jendela terminal. “{}” menyimpan nama direktori saat ini.
  • \; : Ini adalah titik koma yang digunakan untuk mengakhiri perintah. Kita perlu menghindarinya dengan garis miring terbalik agar Bash tidak menafsirkannya secara langsung.

Dengan sedikit perubahan, kita dapat membuat perintah find mengembalikan file yang cocok dengan petunjuk pencarian. Kita perlu menyertakan opsi -name dan petunjuk pencarian. Dalam contoh ini, kami mencari file teks yang cocok dengan “*.txt”, dan mengulangi namanya ke jendela terminal.

 find work -name "*.txt" -type f -execdir echo "Ditemukan:" {} \; 

menggunakan perintah find untuk menemukan file secara rekursif

Apakah Anda mencari file atau direktori tergantung pada apa yang ingin Anda capai. Untuk menjalankan perintah di dalam setiap direktori , gunakan -type d . Untuk menjalankan perintah pada setiap file yang cocok , gunakan -type f .

Perintah ini menghitung baris di semua file teks di direktori awal dan subdirektori.

 temukan pekerjaan -nama "*.txt" -type f -execdir wc -l {} \; 

Menggunakan find dengan perintah wc

TERKAIT: Cara Menggunakan Perintah find di Linux

Melintasi Pohon Direktori Dengan Skrip

Jika Anda perlu melintasi direktori di dalam skrip, Anda dapat menggunakan perintah find di dalam skrip Anda. Jika Anda perlu—atau hanya ingin—melakukan pencarian rekursif sendiri, Anda juga bisa melakukannya.

 #!/bin/bash

shopt -s dotglob nullglob

fungsi rekursif {

  lokal current_dir dir_or_file

  untuk current_dir di $1; melakukan

    echo "Perintah direktori untuk:" $current_dir

    untuk dir_or_file di "$current_dir"/*; melakukan

      if [[ -d $dir_or_file ]]; kemudian
        rekursif "$dir_or_file"
      kalau tidak
        wc $dir_or_file
      fi
    selesai
  selesai
}

rekursif "$1"

Salin teks ke editor dan simpan sebagai "recurse.sh", lalu gunakan perintah chmod untuk membuatnya dapat dieksekusi.

 chmod +x recurse.sh 

Membuat skrip recurse.sh dapat dieksekusi

Script menetapkan dua opsi shell, dotglob dan nullglob .

Pengaturan dotglob berarti nama file dan direktori yang dimulai dengan titik “ . ” akan dikembalikan ketika istilah pencarian wildcard diperluas. Ini secara efektif berarti kami menyertakan file dan direktori tersembunyi di hasil pencarian kami.

Pengaturan nullglob berarti pola pencarian yang tidak menemukan hasil apa pun diperlakukan sebagai string kosong atau null. Mereka tidak default ke istilah pencarian itu sendiri. Dengan kata lain, jika kita mencari segala sesuatu di direktori dengan menggunakan wildcard asterisk “ * “, tetapi tidak ada hasil, kita akan menerima string null alih-alih string yang berisi asterisk. Ini mencegah skrip mencoba membuka direktori yang disebut "*", atau memperlakukan "*" sebagai nama file secara tidak sengaja.

Selanjutnya, ia mendefinisikan fungsi yang disebut recursive . Di sinilah hal menarik terjadi.

Dua variabel dideklarasikan, disebut current_dir dan dir_or_file . Ini adalah variabel lokal, dan hanya dapat direferensikan di dalam fungsi.

Variabel yang disebut $1 juga digunakan dalam fungsi. Ini adalah parameter pertama (dan satu-satunya) yang diteruskan ke fungsi saat dipanggil.

Primer: Bash Loop: untuk, sementara, dan sampai
Primer TERKAIT : Bash Loops: untuk, sementara, dan sampai

Script menggunakan dua for loop, satu bersarang di dalam yang lain. Yang pertama (luar) for loop digunakan untuk dua hal.

Salah satunya adalah menjalankan perintah apa pun yang ingin Anda lakukan di setiap direktori. Semua yang kita lakukan di sini adalah menggemakan nama direktori ke jendela terminal. Anda tentu saja dapat menggunakan perintah atau urutan perintah apa pun, atau memanggil fungsi skrip lain.

Hal kedua yang dilakukan loop for luar adalah memeriksa semua objek sistem file yang dapat ditemukan—yang akan berupa file atau direktori. Ini adalah tujuan dari loop for dalam. Pada gilirannya, setiap file atau nama direktori diteruskan ke variabel dir_or_file .

Variabel dir_or_file kemudian diuji dalam pernyataan if untuk melihat apakah itu sebuah direktori.

  • Jika ya, fungsi memanggil dirinya sendiri dan meneruskan nama direktori sebagai parameter.
  • Jika variabel dir_or_file bukan direktori, maka itu harus berupa file. Perintah apa pun yang ingin Anda terapkan ke file dapat dipanggil dari klausa else dari pernyataan if . Anda juga dapat memanggil fungsi lain dalam skrip yang sama.

Baris terakhir dalam skrip memanggil fungsi recursive dan meneruskan parameter baris perintah pertama $1 sebagai direktori awal untuk mencari. Inilah yang memulai seluruh proses.

Mari kita jalankan skripnya.

 ./recurse.sh bekerja 

Memproses direktori dari yang paling dangkal hingga yang paling dalam

Direktori dilintasi, dan titik dalam skrip di mana perintah akan dijalankan di setiap direktori ditunjukkan oleh baris "Perintah direktori untuk:". File yang ditemukan menjalankan perintah wc untuk menghitung baris, kata, dan karakter.

Direktori pertama yang diproses adalah "work", diikuti oleh setiap cabang direktori bersarang dari pohon.

Hal menarik yang perlu diperhatikan adalah Anda dapat mengubah urutan pemrosesan direktori, dengan memindahkan perintah khusus direktori dari di atas loop for dalam menjadi di bawahnya.

Mari kita pindahkan baris "Directory command for:" ke setelah done loop for dalam.

 #!/bin/bash

shopt -s dotglob nullglob

fungsi rekursif {

  lokal current_dir dir_or_file

  untuk current_dir di $1; melakukan

    untuk dir_or_file di "$current_dir"/*; melakukan

      if [[ -d $dir_or_file ]]; kemudian
        rekursif "$dir_or_file"
      kalau tidak
        wc $dir_or_file
      fi

    selesai

    echo "Perintah direktori untuk:" $current_dir

  selesai
}

rekursif "$1"

Sekarang kita akan menjalankan skrip sekali lagi.

 ./recurse.sh bekerja 

Memproses direktori dari yang terdalam hingga yang paling dangkal

Kali ini direktori memiliki perintah yang diterapkan pada mereka dari level terdalam terlebih dahulu, mengerjakan kembali cabang-cabang pohon. Direktori yang diteruskan sebagai parameter ke skrip diproses terakhir.

Jika penting untuk memproses direktori yang lebih dalam terlebih dahulu, ini adalah bagaimana Anda dapat melakukannya.

Rekursi Itu Aneh

Ini seperti menelepon diri sendiri di telepon Anda sendiri, dan meninggalkan pesan untuk diri sendiri untuk memberi tahu diri Anda sendiri ketika Anda bertemu lagi—berulang kali.

Dibutuhkan beberapa upaya sebelum Anda memahami manfaatnya, tetapi ketika Anda melakukannya, Anda akan melihat itu adalah cara yang elegan secara terprogram untuk mengatasi masalah yang sulit.

TERKAIT: Apa itu Rekursi dalam Pemrograman, dan Bagaimana Anda Menggunakannya?