Giải thích các tùy chọn tìm -path và -prune


11

Tôi có một đoạn script đơn giản mà tôi hiểu hầu hết, đó là lệnh find không rõ ràng. Tôi đã có rất nhiều tài liệu nhưng nó không phục vụ để làm cho nó rõ ràng hơn nhiều. Tôi nghĩ rằng nó hoạt động giống như một vòng lặp for, tệp hiện được tìm thấy được hoán đổi cho {} và được sao chép sang $ HOME / $ dir_name, nhưng tìm kiếm với -path-prune -o hoạt động như thế nào? Thật khó chịu khi có tài liệu cụ thể và có liên quan như vậy mà vẫn không biết chuyện gì đang xảy ra.

#!/bin/bash
# The files will be search on from the user's home
# directory and can only be backed up to a directory
# within $HOME

read -p "Which file types do you want to backup " file_suffix
read -p "Which directory do you want to backup to " dir_name

# The next lines creates the directory if it does not exist
test -d $HOME/$dir_name || mkdir -m 700 $HOME/$dir_name

# The find command will copy files that match the
# search criteria ie .sh . The -path, -prune and -o
# options are to exclude the backdirectory from the
# backup.
find $HOME -path $HOME/$dir_name -prune -o \
-name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;
exit 0

Đây chỉ là tài liệu mà tôi biết tôi có thể tìm ra điều này.

mô hình đường dẫn

Tên tệp phù hợp với mẫu vỏ. Các siêu nhân vật không điều trị / hoặc . đặc biệt; vì vậy, ví dụ, tìm. -path "./sr*sc" sẽ in một mục nhập cho một thư mục có tên ./src/misc (nếu có). Để bỏ qua toàn bộ cây thư mục, hãy sử dụng -prune thay vì kiểm tra mọi tệp trong cây. Ví dụ: để bỏ qua thư mục src / emacs và tất cả các tệp và thư mục bên dưới nó, và in tên của các tệp khác được tìm thấy, hãy làm một cái gì đó như thế này:

find . -path ./src/emacs -prune -o -print

Từ hướng dẫn sử dụng Findutils

- Hành động: lệnh -exec; Biến thể không an toàn này của hành động -execdir được chỉ định bởi POSIX. Sự khác biệt chính là lệnh được thực thi trong thư mục mà từ đó find được gọi, nghĩa là {} được mở rộng thành một đường dẫn tương đối bắt đầu bằng tên của một trong các thư mục bắt đầu, thay vì chỉ tên cơ sở của tệp phù hợp.

Trong khi một số triển khai tìm kiếm thay thế {} chỉ khi nó tự xuất hiện trong một đối số, GNU find sẽ thay thế {} bất cứ nơi nào nó xuất hiện.

Ví dụ: để so sánh từng tệp tiêu đề C trong hoặc bên dưới thư mục hiện tại với tệp / tmp / master:

      find . -name '*.h' -execdir diff -u '{}' /tmp/master ';'


Tôi nghĩ rằng nếu bất cứ điều gì đó là một bản sao của đường dẫn tìm được giải thích ngay cả khi câu trả lời tại find: prune không bỏ qua đường dẫn được chỉ định có câu trả lời dường như áp dụng cho câu hỏi này. Có thể các câu trả lời giải thích tìm đường có ý nghĩa với một người có kinh nghiệm hơn với việc viết kịch bản, nhưng họ không giúp tôi. Các câu trả lời ở đây có ý nghĩa hơn đối với tôi cho đến nay, mặc dù tôi mới bắt đầu tìm hiểu chúng.
flerb

Câu trả lời:


23

-pathhoạt động chính xác như thế -name, nhưng áp dụng mẫu cho toàn bộ tên đường dẫn của tệp đang được kiểm tra, thay vì cho thành phần cuối cùng.

-prune cấm giảm xuống dưới tập tin tìm thấy, trong trường hợp đó là một thư mục.

Đặt tất cả lại với nhau, lệnh

find $HOME -path $HOME/$dir_name -prune -o -name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;
  1. Bắt đầu tìm kiếm các tập tin trong $HOME.
  2. Nếu nó tìm thấy một tập tin phù hợp $HOME/$dir_namethì nó sẽ không nằm dưới nó ("cắt xén" thư mục con).
  3. Mặt khác ( -o) nếu nó tìm thấy một tệp phù hợp *$file_suffixsao chép nó vào $HOME/$dir_name/.

Ý tưởng này dường như là một bản sao lưu một số nội dung $HOMEtrong thư mục con của $HOME. Các bộ phận -prunerõ ràng là cần thiết để tránh tạo bản sao lưu dự phòng ...


Nếu tôi hiểu thì: find sẽ lặp qua từng thư mục trong $ HOME mà nó có quyền truy cập, ngoại trừ $ HOME / $ dir_name, nó sẽ không đi xuống (vì hành động cắt tỉa sẽ đánh giá là đúng và sẽ không được thực hiện), tìm kiếm các tệp kết thúc bằng $ file_suffix. Sau đó, ngay khi tìm thấy, nó sẽ thực hiện cp "Found_file.sh" thành $ HOME / $ dir_name? Ngoài ra, -path cho phép đường dẫn đến một tệp và có hữu ích khi bạn muốn tìm xuống thư mục và không chỉ hoạt động trong thư mục hiện tại?
flerb

Sự hiểu biết của bạn là gần như chính xác. -pathhoạt động giống như -name: nó chọn tập tin. Sự khác biệt là -namekhớp mẫu với tên tệp, trong khi -pathkhớp mẫu với tên đường dẫn đầy đủ. findluôn rơi vào thư mục con, trừ khi ngăn ngừa bằng cách -maxdepthhoặc -prune, vv
AlexP

Oh! -path đang được áp dụng cho $ HOME / $ dir_name -prune sau đó, đó là thứ tự các lệnh gây rối cho tôi và -path là cần thiết cho lệnh prune vì nó cần khớp với đường dẫn đầy đủ của thư mục được cắt tỉa.
flerb

@Darren Tôi không chắc là nó khá chính xác. -path $HOME/$dir_namelà một hành động. Đây là một bài kiểm tra kiểm tra xem đường dẫn của tệp hiện tại đang được kiểm tra có khớp với bất kỳ thứ gì không $HOME/$dir_name. -prunelà một hành động riêng biệt. Tôi nghĩ rằng câu đầu tiên của bình luận đầu tiên của bạn phản ánh chính xác cách thức hoạt động.
David Z

Nó sẽ thiếu một cái gì đó để xem nó như một đường ống? Tôi đã trao đổi -prune với -print và nghĩ rằng dòng chảy đã rõ ràng: tìm $ HOME | -path $ HOME / $ dir_name | -print
flerb

4

Nó là một phần của lệnh find, câu lệnh -exec.

Nó cho phép bạn tương tác với tập tin / thư mục được tìm thấy bởi findlệnh.

find $HOME -path $HOME/$dir_name -prune -o -name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;

find $HOME có nghĩa là tìm tập tin / thư mục trong $ HOME

Để hiểu -path <some_path>, hãy xem `find -path` giải thích

Để hiểu -prune, hãy xem /programming/1361277/how-to-use-prune-option-of-find-in-sh

-ocó nghĩa là HOẶC, vì vậy -path <some_path>HOẶC-name *$file_suffix

-exec nghĩa là thực thi lệnh.

cp {} $HOME/$dir_name/ sao chép bất kỳ tập tin phù hợp với $HOME/$dir_name/

\;có nghĩa là chấm dứt -execlệnh

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.