Có nghĩa là gì {} \; có nghĩa là gì trong lệnh find?


38

Đôi khi tôi thấy lệnh sau:

find . -name  * -exec ls -a {} \;

Tôi đã được yêu cầu thực hiện điều này.

Không gì {} \;có nghĩa là ở đây?


2
-name *là dư thừa.
Kevin

3
Ngoài ra kiểm tra giải thích cho các loại câu hỏi khác như thế này. Đây là đầu ra cho lệnh của bạn. .
Glutimate

10
-name *tồi tệ hơn dự phòng. Vì không *được trích dẫn, trình bao mở rộng nó vào danh sách tên tệp trong thư mục hiện tại, với các khoảng trắng được xử lý không chính xác, dẫn đến kết quả không mong muốn hoặc thông báo lỗi. Là một điểm bổ sung, findcó nhiều chức năng, một trong số đó là liệt kê các tệp; Điều này tránh phải sử dụng -exec. Ví dụ, bạn có thể sử dụng find . -printhoặc find . -ls. Cuối cùng, có hai cách để thoát dấu chấm phẩy: như bạn đã làm với dấu gạch chéo ngược \;hoặc bằng cách trích dẫn : ';'. Sử dụng bất cứ điều gì bạn cảm thấy thoải mái hơn.
Paddy Landau

Câu trả lời:


49

Nếu bạn chạy findvới exec, hãy {}mở rộng tên tệp của từng tệp hoặc thư mục được tìm thấy find(để lstrong ví dụ của bạn lấy mọi tên tệp được tìm thấy làm đối số - lưu ý rằng nó gọi lshoặc bất kỳ lệnh nào khác bạn chỉ định một lần cho mỗi tệp được tìm thấy).

Dấu chấm phẩy ;kết thúc lệnh được thực thi bởi exec. Nó cần phải được thoát ra \để cái vỏ bạn chạy findbên trong không coi nó là đặc tính riêng của nó, mà là chuyển nó sang find.

Xem bài viết này để biết thêm chi tiết.


Ngoài ra, findcung cấp một số tối ưu hóa với exec cmd {} +- khi chạy như vậy, findnối các tệp được tìm thấy vào cuối lệnh thay vì gọi nó một lần cho mỗi tệp (để lệnh chỉ được chạy một lần, nếu có thể).

Sự khác biệt trong hành vi (nếu không hiệu quả) có thể dễ dàng nhận thấy nếu chạy với ls, vd

find ~ -iname '*.jpg' -exec ls {} \;
# vs
find ~ -iname '*.jpg' -exec ls {} +

Giả sử bạn có một số jpgtệp (với các đường dẫn đủ ngắn ), kết quả là một dòng trên mỗi tệp trong trường hợp đầu tiên và lshành vi tiêu chuẩn hiển thị tệp trong các cột cho sau.


1
Tôi nghĩ rằng nó sẽ có lợi cho bạn để tương phản \;với +.
Kevin

Nó khác với find . -name * | ls -a -như thế nào?
András Hummer

@DrH Vấn đề không phải là để shell thực hiện việc mở rộng ký tự đại diện mà là chuyển biểu thức ký tự đại diện sang find. Ngoài ra, đầu ra lstrong trường hợp này rõ ràng không phụ thuộc vào đầu vào - bất kể tôi sử dụng làm bộ lọc để làm gì find, lschỉ hiển thị nội dung thư mục làm việc và đó là tất cả. Kiểm tra ví dụ find ~ -iname '*.jpg' -exec ls -a {} \;vs find ~ -iname '*.jpg' | ls -a.
moon.musick

@DrH hoặc thậm chí echo 'foo' | ls -a.
moon.musick

@ moon.musick, tôi tin rằng bạn đã bỏ lỡ điều quan trọng -trong ls -a -lệnh của mình khi kiểm tra những gì @ dr-h truy vấn.
Daniel Llewellyn

21

Từ trang hướng dẫn cho findlệnhBiểu tượng trang :

-exec command ;
              Execute  command;  true if 0 status is returned.  All following arguments to find are taken to be arguments to
              the command until an argument consisting of `;' is encountered.  The string `{}' is replaced  by  the  current
              file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it
              is alone, as in some versions of find.  Both of these constructions might need to be escaped (with a  `\')  or
              quoted  to  protect them from expansion by the shell.

Vì vậy, đây là lời giải thích:

{}có nghĩa là "đầu ra của find". Như trong, "bất cứ điều gì findtìm thấy". findtrả về đường dẫn của tệp bạn đang tìm, phải không? Vì vậy, {}thay thế nó; đó là một trình giữ chỗ cho mỗi tệp mà findlệnh định vị (được lấy từ đây ).

Phần \;cơ bản là nói find"được thôi, tôi đã thực hiện xong lệnh tôi muốn thực thi".

Thí dụ:

Giả sử tôi đang ở trong một thư mục chứa đầy các .txttập tin. Sau đó tôi chạy:

find . -name  '*.txt' -exec cat {} \;

Phần đầu tiên find . -name *.txt, trả về một danh sách các .txttập tin. Phần thứ hai, -exec cat {} \;sẽ thực thi catlệnh cho mọi tệp được tìm thấy bởi find, vì vậy cat file1.txt, cat file2.txtv.v.


4
Phần *.txtphải được trích dẫn là '*.txt'. Điều này là do nếu có .txtcác tệp trong thư mục hiện tại, trình bao sẽ mở rộng điều này và bạn sẽ nhận được kết quả không chính xác hoặc thông báo lỗi. find -name '*.txt' -exec cat {} \;
Paddy Landau

@Alaa Ali giải thích rất rõ
Pushya
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.