Hãy tưởng tượng một cây nguồn. Có tập tin xml ở khắp mọi nơi.
Nhưng vì có một XYZ.xml ở gốc của cây này nên nó sẽ không tìm thấy các tệp xml của tôi.
find -iname *.xml
trả lại
./XYZ.xml
thay vì
./XYZ.xml
./a/b/c/bob.xml
./b/d/top.xml
Hãy tưởng tượng một cây nguồn. Có tập tin xml ở khắp mọi nơi.
Nhưng vì có một XYZ.xml ở gốc của cây này nên nó sẽ không tìm thấy các tệp xml của tôi.
find -iname *.xml
trả lại
./XYZ.xml
thay vì
./XYZ.xml
./a/b/c/bob.xml
./b/d/top.xml
Câu trả lời:
find -iname '*.xml'
Mặt khác, shell của bạn mở rộng *.xmlthành XYZ.xmlvà lệnh thực sự được thực thi là
find -iname XYZ.xml
Lý do nó hoạt động nếu không có tệp XML trong thư mục hiện tại là vì các shell thường để các ký tự đại diện chưa được mở rộng nếu chúng không khớp với bất cứ thứ gì. Nói chung, bất cứ lúc nào bạn muốn ký tự đại diện để được mở rộng bằng một chương trình khác hơn so với vỏ (ví dụ bằng find, tar, scp, vv), bạn cần phải trích dẫn họ để vỏ sẽ không cố gắng để mở rộng chúng riêng của mình.
bashchứ không phải của find.
Bạn cần trích dẫn lập luận của bạn như thế này:
find ./ -name '*.xml'
để nó được chuyển qua để tìm thay vì được mở rộng bằng shell, sau đó được chuyển qua để tìm làm phiên bản mở rộng.
*.xmlkhông khớp với bất cứ thứ gì trong thư mục hiện tại, nó được truyền theo nghĩa đen, đó là lý do tại sao nó hoạt động trong trường hợp khác. Câu trả lời rất hữu ích.
Ký tự đại diện được mở rộng bằng vỏ chứ không phải bằng lệnh. findlà một trong số ít các lệnh thực hiện khớp ký tự đại diện tương tự như shell, trong thời gian riêng của nó.
Khi bạn chạy ls *.xml, đầu tiên shell sẽ mở rộng ra *.xmldanh sách các tệp phù hợp, ví dụ file1.xml file2.xml file3.xml, sau đó shell gọi lsvới danh sách các đối số kết quả file1.xml file2.xml file3.xml. Đó là lý do tại sao bạn thấy cùng một danh sách tên tệp echo *.xml, mặc dù echokhông biết gì về tệp và không quan tâm liệu đối số của nó có phải là tên tệp hay không.
Khi bạn chạy find . -name "*.xml":
find, ., -name, *.xmlnơi *được trích dẫn. Vì *được trích dẫn, nó là một nhân vật bình thường khi có liên quan đến cái vỏ.findvới danh sách cụ thể các đối số: ., -name, *.xml.findtìm kiếm các tệp có tên khớp với mẫu *.xmltrong bất kỳ thư mục nào trong thư mục hiện tại.Khi bạn chạy find . -name *.xmlvà không có tệp nào khớp *.xml:
find, ., -name, *.xmlnơi *không được trích dẫn.*.xmlnày chứa ký tự đại diện không được trích dẫn, shell thực hiện việc tạo tên tệp. Vì không có tên tệp phù hợp, mẫu vẫn chưa được mở rộng.findvới kết quả là danh sách các đối số, đó là ., -name, *.xml.findtìm kiếm các tệp có tên khớp với mẫu *.xmltrong bất kỳ thư mục nào trong thư mục hiện tại.Khi bạn chạy find . -name *.xmlvà thư mục hiện tại chứa file1.xml, file2.xmlvà file3.xml:
find, ., -name, *.xmlnơi *không được trích dẫn.*.xmlchứa ký tự đại diện không được trích dẫn, shell thực hiện việc tạo tên tệp: *.xmlđược thay thế bằng danh sách các tên tệp phù hợp.findvới kết quả là danh sách các đối số, đó là ., -name, file1.xml, file2.xml, file3.xml.findphàn nàn về một lỗi cú pháp khi nó đạt đến file2.xml.Khi bạn chạy find . -name *.xmlvà thư mục hiện tại chứa một tệp phù hợp file.xml:
find, ., -name, *.xmlnơi *không được trích dẫn.*.xmlchứa ký tự đại diện không được trích dẫn, shell thực hiện việc tạo tên tệp: *.xmlđược thay thế bằng danh sách các tên tệp phù hợp.findvới kết quả là danh sách các đối số, đó là ., -name, file.xml.findthấy một lệnh hoàn toàn hợp lệ, nhưng nó có thể không phải là những gì bạn dự định: findđược yêu cầu tìm các tệp được gọi file.xmltrong bất kỳ thư mục nào, không tìm kiếm bất kỳ tệp nào khớp *.xml.(Đánh giá và mở rộng Shell có rất nhiều tính năng khác. Tôi chỉ đề cập đến những tính năng có liên quan ở đây.)
(Những gì tôi mô tả là hành vi mặc định của hầu hết các shell phổ biến: sh, bash, dash, ksh,. danh sách. Không ai trong số họ sẽ giúp ở đây.)
Điều này hoạt động trên Solaris 10:
find /directory-to-search/* -prune -name "*gz"
.xml.
Vui lòng thử:
find ./ -name *.xml
*luôn nên được trích dẫn hoặc thoát để vượt qua nó để tìm.
man find: Xin lưu ý rằng bạn nên trích dẫn các mẫu như một vấn đề tất nhiên, nếu không, trình bao sẽ mở rộng bất kỳ ký tự đại diện nào trong chúng.