วิธีการของ @ meuh ไม่มีประสิทธิภาพเนื่องจาก-maxdepth 1วิธีการของเขายังช่วยให้findอ่านเนื้อหาของไดเรกทอรีที่ระดับ 1 เพื่อเพิกเฉยต่อสิ่งเหล่านี้ในภายหลัง มันจะไม่ทำงานอย่างถูกต้องกับfindการใช้งานบางอย่าง(รวมถึง GNU find) ถ้าบางชื่อไดเรกทอรีมีลำดับของไบต์ที่ไม่ได้สร้างตัวละครที่ถูกต้องในสถานที่ของผู้ใช้ (เช่นชื่อไฟล์ในการเข้ารหัสอักขระที่แตกต่างกัน)
find . \( -name . -o -prune \) -extra-conditions-and-actions
เป็นวิธีที่ยอมรับได้มากขึ้นในการใช้ GNU -maxdepth 1(หรือ FreeBSD's -depth -2)
โดยทั่วไปแล้ว-depth 1คุณต้องการ ( -mindepth 1 -maxdepth 1) ตามที่คุณไม่ต้องการพิจารณา.(ความลึก 0) จากนั้นง่ายยิ่งขึ้น:
find . ! -name . -prune -extra-conditions-and-actions
สำหรับ-maxdepth 2ที่จะกลายเป็น:
find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
และนั่นคือสิ่งที่คุณทำงานในปัญหาของตัวละครที่ไม่ถูกต้อง
ตัวอย่างเช่นหากคุณมีไดเรกทอรีที่เรียกว่าStéphaneแต่éมีการเข้ารหัสในชุดอักขระ iso8859-1 (aka latin1) (0xe9 ไบต์) ซึ่งพบได้ทั่วไปในยุโรปตะวันตกและอเมริกาจนถึงกลางปี 2000 ดังนั้น 0xe9 ไบต์จะไม่เป็น อักขระที่ถูกต้องใน UTF-8 ดังนั้นในโลแคล UTF-8 *อักขระตัวแทน (ที่มีfindการใช้งานบางอย่าง) จะไม่ตรงกับStéphaneที่*เป็น 0 หรือมากกว่าตัวอักษรและ 0xe9 ไม่ใช่ตัวอักษร
$ locale charmap
UTF-8
$ find . -maxdepth 2
.
./St?phane
./St?phane/Chazelas
./Stéphane
./Stéphane/Chazelas
./John
./John/Smith
$ find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St?phane/Chazelas/age
./St?phane/Chazelas/gender
./St?phane/Chazelas/address
./Stéphane
./Stéphane/Chazelas
./John
./John/Smith
ของฉันfind(เมื่อผลลัพธ์ไปยังเทอร์มินัล) แสดง 0xe9 ไบต์ที่ไม่ถูกต้องดังกล่าว?ข้างต้น คุณจะเห็นว่าSt<0xe9>phane/Chazelasไม่ใช่pruned
คุณสามารถหลีกเลี่ยงได้โดยทำ:
LC_ALL=C find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
แต่โปรดทราบว่าจะมีผลกับการตั้งค่าภาษาทั้งหมดfindและแอปพลิเคชันใด ๆ ที่ทำงาน (เช่นผ่านภาค-execแสดง)
$ LC_ALL=C find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St??phane
./St??phane/Chazelas
./John
./John/Smith
ตอนนี้ฉันได้รับจริง ๆ-maxdepth 2แต่ทราบว่าéในStéphaneที่สองถูกเข้ารหัสอย่างถูกต้องใน UTF-8 แสดงเป็น??อย่างไร 0xc3 0xa9 ไบต์ (ถือว่าเป็นอักขระสองตัวที่ไม่ได้กำหนดใน C ตำแหน่งที่ตั้ง) ของการเข้ารหัส UTF-8 ของé ไม่ใช่อักขระที่พิมพ์ได้ใน C locale
และถ้าฉันเพิ่ม a ลงไป-name '????????'ฉันจะได้ค่าStéphaneผิด (อันที่เข้ารหัสใน iso8859-1)
หากต้องการนำไปใช้กับเส้นทางที่กำหนดเองแทนคุณ.จะต้อง:
find some/dir/. ! -name . -prune ...
สำหรับ-mindepth 1 -maxdepth 1หรือ:
find some/dir/. \( ! -path '*/./*/*' -o -prune \) ...
-maxdepth 2สำหรับ
ฉันจะยังคงทำ:
(cd -P -- "$dir" && find . ...)
ก่อนเพราะนั่นทำให้เส้นทางสั้นลงซึ่งทำให้มีโอกาสน้อยที่จะวิ่งเข้าไปในเส้นทางยาวเกินไปหรือหาเรื่องรายการปัญหาที่ยาวเกินไปแต่ยังต้องหลีกเลี่ยงข้อเท็จจริงที่findไม่สามารถรองรับอาร์กิวเมนต์เส้นทางโดยพลการ (ยกเว้น-fกับ FreeBSD find) เนื่องจากจะทำให้หายใจไม่ออก ค่า$dirชอบ!หรือ-print...
-oรวมกันด้วยการปฏิเสธเป็นเคล็ดลับเรื่องธรรมดาที่จะเรียกใช้สองชุดเป็นอิสระจาก-condition/ ใน-actionfind
หากคุณต้องการทำงาน-action1กับการประชุมไฟล์-condition1และเป็นอิสระ-action2ในการประชุมไฟล์-condition2คุณไม่สามารถทำได้:
find . -condition1 -action1 -condition2 -action2
เช่น-action2เดียวกับที่จะเรียกใช้สำหรับไฟล์ที่ตรงตามเงื่อนไขทั้งสอง
มิได้:
find . -contition1 -action1 -o -condition2 -action2
ในฐานะที่-action2จะไม่ถูกเรียกใช้ไฟล์ที่ตอบสนองทั้งเงื่อนไข
find . \( ! -condition1 -o -action1 \) -condition2 -action2
ทำงานตามที่\( ! -condition1 -o -action1 \)ต้องการจะแก้ไขเป็นจริงสำหรับทุกไฟล์ ที่ถือว่า-action1เป็นกระทำ (เช่น-prune, -exec ... {} +) ที่เสมอกลับจริง สำหรับการดำเนินการเช่น-exec ... \;นั้นอาจส่งคืนค่าเท็จคุณอาจต้องการเพิ่มรายการอื่น-o -somethingที่-somethingไม่เป็นอันตราย แต่ส่งกลับค่าจริงเช่น-trueใน GNU findหรือ-links +0หรือ -name '*'(ถึงแม้ว่าจะบันทึกปัญหาเกี่ยวกับอักขระที่ไม่ถูกต้องด้านบน)
-depth -2,-depth 1... สามารถมองเห็นวิธีการได้ดีกว่า GNU's-maxdepth/-mindepth