Cách duyệt cây thư mục trên Linux

[ad_1]

fatmawati achmad zaenuri / Shutterstock.com

Các thư mục trên Linux cho phép bạn nhóm các tệp trong các bộ sưu tập riêng biệt, riêng biệt. Nhược điểm là nó trở nên tẻ nhạt khi di chuyển từ thư mục này sang thư mục khác để thực hiện một nhiệm vụ lặp đi lặp lại. Đây là cách để tự động hóa điều đó.

Tất cả Giới thiệu về Thư mục

Lệnh đầu tiên bạn học khi làm quen với Linux có thể là lsnhưng cd sẽ không bị bỏ xa sau nó. Hiểu các thư mục và cách di chuyển xung quanh chúng, đặc biệt là các thư mục con lồng nhau, là một phần cơ bản để hiểu cách Linux tự tổ chức và cách bạn có thể tổ chức công việc của mình thành các tệp, thư mục và thư mục con.

Nắm bắt khái niệm về một cây thư mục — và cách di chuyển giữa chúng — là một trong nhiều cột mốc quan trọng mà bạn vượt qua khi làm quen với bối cảnh của Linux. Sử dụng cd với một đường dẫn đưa bạn đến thư mục đó. Các phím tắt như cd ~ hoặc cd tự nó sẽ đưa bạn trở lại thư mục chính của bạn và cd .. di chuyển bạn lên một cấp trong cây thư mục. Giản dị.

Tuy nhiên, không có một phương tiện đơn giản như nhau để chạy một lệnh trong tất cả các thư mục của cây thư mục. Có nhiều cách khác nhau để chúng ta có thể đạt được chức năng đó, nhưng không có lệnh Linux tiêu chuẩn nào dành riêng cho mục đích đó.

Một số lệnh, chẳng hạn như lscó các tùy chọn dòng lệnh buộc chúng phải hoạt động đệ quy, nghĩa là chúng bắt đầu trong một thư mục và hoạt động theo phương pháp thông qua toàn bộ cây thư mục bên dưới thư mục đó. Vì lsđó là -R (đệ quy) tùy chọn.

Nếu bạn cần sử dụng lệnh không hỗ trợ đệ quy, bạn phải tự cung cấp chức năng đệ quy. Đây là cách để làm điều đó.

CÓ LIÊN QUAN: 37 lệnh quan trọng trong Linux bạn nên biết

Lệnh cây

Các tree lệnh sẽ không giúp chúng ta thực hiện nhiệm vụ trong tầm tay, nhưng nó giúp bạn dễ dàng nhìn thấy cấu trúc của cây thư mục. Nó vẽ cây trong cửa sổ đầu cuối để chúng ta có thể có cái nhìn tổng quan tức thì về các thư mục và thư mục con tạo nên cây thư mục và vị trí tương đối của chúng trong cây.

Bạn sẽ cần cài đặt tree .

Trên Ubuntu, bạn cần nhập:

sudo apt install tree

Cài đặt cây trên Ubuntu

Trên Fedora, sử dụng:

sudo dnf install tree

Cài đặt cây trên Fedora

Trên Manjaro, lệnh là:

sudo pacman -Sy tree

Cài đặt cây trên Manjaro

Sử dụng tree không có tham số vẽ ra cây bên dưới thư mục hiện tại.

tree

Cây đang chạy trong thư mục hiện tại

Bạn có thể vượt qua một con đường để tree trên dòng lệnh.

tree work

Chạy cây trên một thư mục cụ thể

Các -d (thư mục) tùy chọn loại trừ các tệp và chỉ hiển thị các thư mục.

tree -d work

Cây đang chạy và chỉ hiển thị các thư mục

Đây là cách thuận tiện nhất để có cái nhìn rõ ràng về cấu trúc của cây thư mục. Cây thư mục được hiển thị ở đây là cây được sử dụng trong các ví dụ sau. Có năm tệp văn bản và tám thư mục.

Không phân tích cú pháp đầu ra từ ls đến các thư mục Traverse

Suy nghĩ đầu tiên của bạn có thể là, nếu ls có thể duyệt đệ quy một cây thư mục, tại sao không sử dụng ls để làm điều đó và chuyển đầu ra thành một số lệnh khác phân tích cú pháp các thư mục và thực hiện một số hành động?

Phân tích cú pháp đầu ra của ls được coi là thực hành xấu. Do khả năng trong Linux có thể tạo tên tệp và thư mục chứa tất cả các loại ký tự lạ, nên rất khó để tạo ra một trình phân tích cú pháp chung, chính xác.

Bạn có thể không bao giờ cố ý tạo một tên thư mục phi lý như thế này, nhưng có thể xảy ra sai sót trong tập lệnh hoặc ứng dụng.

Một tên thư mục kỳ lạ

Việc phân tích cú pháp các tên tệp và thư mục hợp pháp nhưng được coi là kém dễ xảy ra lỗi. Có những phương pháp khác mà chúng tôi có thể sử dụng an toàn hơn và mạnh mẽ hơn nhiều so với việc dựa vào việc diễn giải kết quả đầu ra của ls.

Sử dụng lệnh find

Các find lệnh có các khả năng đệ quy được tích hợp sẵn và nó cũng có khả năng chạy các lệnh cho chúng ta. Điều này cho phép chúng tôi xây dựng một lớp lót mạnh mẽ. Nếu đó là thứ mà bạn có khả năng muốn sử dụng trong tương lai, bạn có thể biến một lớp lót của mình thành một bí danh hoặc một hàm shell.

Lệnh này lặp một cách đệ quy qua cây thư mục, tìm kiếm các thư mục. Mỗi khi tìm thấy một thư mục, nó sẽ in ra tên của thư mục đó và lặp lại việc tìm kiếm bên trong thư mục đó. Sau khi hoàn thành việc tìm kiếm một thư mục, nó thoát khỏi thư mục đó và tiếp tục tìm kiếm trong thư mục mẹ của nó.

find work -type d -execdir echo "In:" {} ;

sử dụng lệnh find để tìm các thư mục một cách đệ quy

Bạn có thể xem theo thứ tự các thư mục được liệt kê, cách tìm kiếm tiến triển qua cây. Bằng cách so sánh kết quả đầu ra từ tree lệnh đến đầu ra từ find một lớp lót, bạn sẽ thấy cách find lần lượt tìm kiếm từng thư mục và thư mục con cho đến khi gặp thư mục không có thư mục con. Sau đó, nó quay trở lại một cấp độ và tiếp tục tìm kiếm ở cấp độ đó.

Đây là cách tạo ra lệnh.

  • tìm thấy: Các find yêu cầu.
  • công việc: Thư mục để bắt đầu tìm kiếm. Đây có thể là một đường dẫn.
  • -loại d: Chúng tôi đang tìm kiếm các thư mục.
  • -execdir: Chúng tôi sẽ thực thi một lệnh trong mỗi thư mục mà chúng tôi tìm thấy.
  • echo “Trong:” {}: Đây là lệnh., Chúng tôi chỉ đơn giản là lặp lại tên của thư mục tới cửa sổ đầu cuối. “{}” Giữ tên của thư mục hiện tại.
  • U0026quot;: Đây là dấu chấm phẩy dùng để kết thúc lệnh. Chúng ta cần thoát khỏi nó bằng dấu gạch chéo ngược để Bash không diễn giải nó một cách trực tiếp.

Với một chút thay đổi, chúng ta có thể làm cho lệnh find trả về các tệp khớp với một đầu mối tìm kiếm. Chúng tôi cần bao gồm tùy chọn -name và một đầu mối tìm kiếm. Trong ví dụ này, chúng tôi đang tìm kiếm các tệp văn bản khớp với “* .txt” và lặp lại tên của chúng với cửa sổ dòng lệnh.

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

sử dụng lệnh find để tìm tệp một cách đệ quy

Cho dù bạn tìm kiếm tệp hoặc thư mục phụ thuộc vào những gì bạn muốn đạt được. Để chạy một lệnh bên trong mỗi thư mụcsử dụng -type d . Để chạy một lệnh trên mỗi tệp phù hợpsử dụng -type f.

Lệnh này đếm các dòng trong tất cả các tệp văn bản trong thư mục bắt đầu và các thư mục con.

find work -name "*.txt" -type f -execdir wc -l {} ;

Sử dụng find với lệnh wc

CÓ LIÊN QUAN: Cách sử dụng lệnh find trong Linux

Duyệt cây thư mục bằng tập lệnh

Nếu bạn cần duyệt qua các thư mục bên trong một tập lệnh, bạn có thể sử dụng find lệnh bên trong tập lệnh của bạn. Nếu bạn cần — hoặc chỉ muốn — tự thực hiện các tìm kiếm đệ quy, bạn cũng có thể làm điều đó.

#!/bin/bash

shopt -s dotglob nullglob

function recursive và}#13;

  local current_dir dir_or_file

  for current_dir in $1; do

    echo "Directory command for:" $current_dir

    for dir_or_file in "$current_dir"/*; do

      if [[ -d $dir_or_file ]]; then
        recursive "$dir_or_file"
      else
        wc $dir_or_file
      fi
    done
  done
}

recursive "$1"

Sao chép văn bản vào một trình chỉnh sửa và lưu nó dưới dạng “recurse.sh”, sau đó sử dụng chmod lệnh để làm cho nó có thể thực thi được.

chmod +x recurse.sh

Làm cho tập lệnh recurse.sh có thể thực thi được

Tập lệnh đặt hai tùy chọn trình bao, dotglobnullglob.

Các dotglob cài đặt có nghĩa là tên tệp và thư mục bắt đầu bằng dấu chấm “.”Sẽ được trả về khi các cụm từ tìm kiếm theo ký tự đại diện được mở rộng. Điều này có nghĩa là chúng tôi đang bao gồm các tệp và thư mục ẩn trong kết quả tìm kiếm của mình.

Các nullglob cài đặt có nghĩa là các mẫu tìm kiếm không tìm thấy bất kỳ kết quả nào được coi là một chuỗi trống hoặc rỗng. Họ không mặc định cho chính cụm từ tìm kiếm. Nói cách khác, nếu chúng tôi đang tìm kiếm mọi thứ trong một thư mục bằng cách sử dụng ký tự đại diện dấu hoa thị “*“, Nhưng không có kết quả, chúng tôi sẽ nhận được một chuỗi rỗng thay vì một chuỗi có chứa dấu hoa thị. Điều này ngăn tập lệnh vô tình cố gắng mở một thư mục có tên “*” hoặc coi “*” là tên tệp.

Tiếp theo, nó định nghĩa một hàm được gọi là recursive. Đây là nơi những điều thú vị xảy ra.

Hai biến được khai báo, được gọi là current_dirdir_or_file . Đây là các biến cục bộ và chỉ có thể được tham chiếu trong hàm.

Một biến được gọi là $1 cũng được sử dụng trong hàm. Đây là tham số đầu tiên (và duy nhất) được truyền cho hàm khi nó được gọi.

Tập lệnh sử dụng hai for vòng lặp, một cái lồng vào bên trong cái kia. Đầu tiên (bên ngoài) for vòng lặp được sử dụng cho hai điều.

Một là chạy bất kỳ lệnh nào bạn muốn thực hiện trong mỗi thư mục. Tất cả những gì chúng ta đang làm ở đây là lặp lại tên của thư mục tới cửa sổ đầu cuối. Tất nhiên, bạn có thể sử dụng bất kỳ lệnh hoặc chuỗi lệnh nào hoặc gọi một hàm script khác.

Điều thứ hai mà vòng lặp for bên ngoài làm là kiểm tra tất cả các đối tượng hệ thống tệp mà nó có thể tìm thấy — đó sẽ là tệp hoặc thư mục. Đây là mục đích của bên trong for vòng. Đổi lại, mỗi tên tệp hoặc thư mục được chuyển vào dir_or_file Biến đổi.

Các dir_or_file sau đó biến được kiểm tra trong một câu lệnh if để xem nó có phải là một thư mục hay không.

  • Nếu đúng như vậy, hàm sẽ gọi chính nó và chuyển tên của thư mục làm tham số.
  • Nếu dir_or_file biến không phải là một thư mục, thì nó phải là một tệp. Bất kỳ lệnh nào bạn muốn áp dụng cho tệp đều có thể được gọi từ else mệnh đề của if bản tường trình. Bạn cũng có thể gọi một hàm khác trong cùng một tập lệnh.

Dòng cuối cùng trong tập lệnh gọi recursive chức năng và vượt qua trong lần đầu tiên dòng lệnh tham số $1 làm thư mục bắt đầu để tìm kiếm. Đây là thứ bắt đầu toàn bộ quá trình.

Hãy chạy script.

./recurse.sh work

Xử lý các thư mục từ nông nhất đến sâu nhất

Các thư mục được duyệt qua và điểm trong tập lệnh nơi lệnh sẽ được chạy trong mỗi thư mục được chỉ ra bằng dòng “Lệnh thư mục cho:”. Các tệp được tìm thấy có wc chạy lệnh trên chúng để đếm dòng, từ và ký tự.

Thư mục đầu tiên được xử lý là “work”, tiếp theo là mỗi nhánh thư mục lồng nhau của cây.

Một điểm thú vị cần lưu ý là bạn có thể thay đổi thứ tự mà các thư mục được xử lý, bằng cách di chuyển các lệnh dành riêng cho thư mục từ phía trên vòng lặp for bên trong sang bên dưới nó.

Hãy chuyển dòng “Lệnh thư mục cho:” sang sau done của bên trong for vòng.

#!/bin/bash

shopt -s dotglob nullglob

function recursive và}#13;

  local current_dir dir_or_file

  for current_dir in $1; do

    for dir_or_file in "$current_dir"/*; do

      if [[ -d $dir_or_file ]]; then
        recursive "$dir_or_file"
      else
        wc $dir_or_file
      fi

    done

    echo "Directory command for:" $current_dir

  done
}

recursive "$1"

Bây giờ chúng ta sẽ chạy script một lần nữa.

./recurse.sh work

Xử lý các thư mục từ sâu nhất đến nông nhất

Lần này các thư mục có các lệnh được áp dụng cho chúng từ các tầng sâu nhất trước tiên, làm việc sao lưu các nhánh của cây. Thư mục được truyền làm tham số cho tập lệnh được xử lý cuối cùng.

Nếu điều quan trọng là phải xử lý các thư mục sâu hơn trước, thì đây là cách bạn có thể thực hiện.

Đệ quy là kỳ lạ

Nó giống như tự gọi cho chính mình trên điện thoại của bạn và để lại một tin nhắn cho chính bạn để tự nhủ khi gặp bạn lần sau — lặp đi lặp lại.

Có thể mất một chút nỗ lực trước khi bạn nắm bắt được những lợi ích của nó, nhưng khi thực hiện bạn sẽ thấy đó là một cách giải quyết các vấn đề khó theo lập trình một cách thanh lịch.

CÓ LIÊN QUAN: Đệ quy trong lập trình là gì và bạn sử dụng nó như thế nào?



[ad_2]

Đánh giá dịch vụ post
Chat Zalo
0903064855