ค้นหาไฟล์ในหลายชื่อโฟลเดอร์


44

ฉันพยายามที่จะรายการไฟล์ทั้งหมดจากdir1, dir2, dir3และdir4ซึ่งอาจจะเป็นที่ใดก็ได้ในเป็นไดเรกทอรีย่อยของฉันcwdโดยใช้findคำสั่ง ฉันพยายามต่อไปนี้โดยไม่ประสบความสำเร็จ:

find . -type f -regextype posix-egrep -regex 'dir1/.+|dir2/.+|dir3/.+|dir4/.+'

ฉันพยายามposix-extendedเช่นกัน ฉันจะแสดงรายการไฟล์เหล่านี้ได้อย่างไร


หา -type f -regextype sed -regex ". * / dir [1-4] / [a-z0-9] *" .. คำตอบที่สั้นที่สุดจนถึงตอนนี้ :) ดูคำตอบด้านล่าง .. unix.stackexchange.com/a/390333 / 242983
alpha_989

คำตอบ:


59

และถ้าคุณต้องการค้นหาสามโฟลเดอร์ชื่อfoo, barและbazสำหรับทุก*.pyไฟล์ใช้คำสั่งนี้:

find foo bar baz -name "*.py"

ดังนั้นหากคุณต้องการแสดงไฟล์จากการdir1 dir2 dir3ใช้งานfind dir1 dir2 dir3 -type f

ลองนี้ find . \( -name "dir1" -o -name "dir2" \) -exec ls '{}' \;


ฉันควรจะชี้แจง ฉันอาจไม่มีเส้นทางไปยังไฟล์ที่ฉันต้องการค้นหา ฉันรู้ว่าพวกเขาเป็นไดเรกทอรีย่อยของ dir ปัจจุบัน
แอรอน

ใช้./dirแทนdir
harish.venkat

dir ยังคงต้องอยู่ใน cwd ถึงแม้ว่ามันอาจจะต่ำกว่าสองระดับ (เช่น./path/to/dir1) ซึ่งในกรณีนี้./dir1จะไม่มีอยู่
แอรอน

แก้ไขคำตอบ
harish.venkat

8

วิธีที่ดีที่สุดคือใช้คำสั่ง -path:

find .  \( -type f -and -path '*/dir1/*' -or -path '*/dir2/*' -or -path '*/dir3/*' -or -path '*/dir4/*' \)

ซึ่งหมายความว่า: ค้นหาไฟล์ทั้งหมดภายใต้ไดเรกทอรีปัจจุบันที่มี 'dir1' หรือ 'dir2' หรือ 'dir3' หรือ 'dir4' ในพา ธ


คุณมีวงเล็บอยู่ผิดที่ ดูเพิ่มเติม-aและ-oสำหรับเทียบเท่ามาตรฐานของ GNU ของ/-and -or
Stéphane Chazelas

4

เพียงเพื่อให้ทุกคนรู้ การเพิ่ม.*/ก่อนจะdirแก้ปัญหาเนื่องจากการregexจับคู่กับเส้นทางแบบเต็มดูเหมือนว่า


3

นี่เป็นความคิดแรกของฉันหลังจากอ่านคำตอบก่อนหน้า:

find . -type f -regextype posix-egrep -regex ".*/(dir1|dir2|dir3|dir4)/.+"

สิ่งนี้คำนึงถึงว่า regex ต้องตรงกับชื่อไฟล์ทั้งหมดและง่ายต่อการเข้าใจ


2

ตัวอย่างของการค้นหาไฟล์ด่วน (!) โดยเฉพาะ (access_log) ในหลาย ๆ สถานที่ที่กำหนดโดยไวด์การ์ด (โฮมไดเรกทอรี) และไดเรกทอรีบันทึก apache2 ทั่วไปที่ใช้การกรองชื่อเพื่อแยกไฟล์บันทึก ssl และบันทึกเก่า gzipped ไม่ตอบคำถามที่นี่โดยตรง แต่อาจเป็นประโยชน์สำหรับคนที่พบคำแนะนำเหล่านี้ (เช่นฉัน)

find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*"

ระมัดระวังกับพื้นที่พิเศษใกล้และ\(\)

โดยวิธีการที่ฉันใช้มันสำหรับ apachetop เพื่อค้นหาเว็บไซต์ที่ใช้งานมากที่สุดในเซิร์ฟเวอร์ของฉัน

apachetop -d1 -s9 -p $(find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*" -print | sed 's/^/-f '/)

2

คุณไม่จำเป็นต้องระบุ dir1 ถึง dir4 ตามชื่อถ้าคุณใช้ regextype

find . -type f -regextype sed -regex ".*/dir[1-4]/[^/]*"
  • type f: ค้นหาไฟล์ไม่ใช่ไดเรกทอรี
  • regextype sed: ใช้ sed regtytype
  • regex: ค้นหาโดยใช้ regex ตลอดเส้นทาง
  • ".*/dir[1-4]/[a-z0-9]*":. * ที่จุดเริ่มต้นหมายถึงจำนวนอักขระใด ๆ ที่อาจเป็นประเภท (char / number / backslash (/) ฯลฯ ); dir [1-4] หมายถึงค้นหา "dir" ตามด้วยหมายเลขระหว่าง 1 ถึง 4; / [^ /] * ระบุว่าการติดตาม dir1-4 จะไม่ใช้ชื่อพา ธ ใด ๆ ที่มี / ในนั้นดังนั้นจะส่งคืนไฟล์ในไดเรกทอรี dir1-dir4 เท่านั้นและไม่สนใจไดเรกทอรีย่อยใด ๆ ที่อาจอยู่ใน dir1-dir4

สร้างไดเรกทอรีสำหรับคุณเพื่อทดสอบ: https://github.com/alphaCTzo7G/stackexchange/tree/master/linux/findSolution04092017


(1) เราไม่อาจทราบสถานการณ์หรือข้อกำหนดที่แน่นอนของแอรอนได้ แต่คำตอบอื่น ๆ ได้ทำการตัดสินใจอย่างรอบคอบว่าเขามีไดเรกทอรีสี่แห่งซึ่งไม่มีชื่อระบุ (พวกเขาอาจจะred, green, blueและyellowหรือพวกเขาอาจจะJohn, Paul, GeorgeและRingo.) คำตอบของคุณสมมติว่าพวกเขามีตัวอักษร dir1 , dir2, และdir3 dir4… (ต่อ)
สกอตต์

(ต่อ) ... (2) ทำไมคุณถึงคิดว่าแอรอนไม่ต้องการค้นหาไดเรกทอรีย่อย? ดูเหมือนเขาจะบอกว่าเขาทำ (3) ทำไมคุณ จำกัด การค้นหาไฟล์ที่มีชื่อมีเพียงตัวอักษรกรณีที่ต่ำกว่าและตัวเลข (ไม่รวมสิ่งที่ชอบfoo_bar, foo.txtและFOO)? (4) ทำไมข้อความของคุณอธิบาย/[^/]*เมื่อคำตอบของคุณไม่ได้ใช้?
สกอตต์

สวัสดีสกอตต์นั่นคือความคิดเห็นของคุณ
alpha_989

(1-3) เขากล่าวถึง "ฉันพยายามที่จะแสดงรายการไฟล์ทั้งหมดจาก dir1, dir2, dir3 และ dir4 " ซึ่งอาจอยู่ที่ใดก็ได้ในไดเรกทอรีย่อยของ cwd ของฉันซึ่งหมายความว่า dir1-dir4 อาจอยู่ที่ใดก็ได้ แต่เขาต้องการค้นหาไฟล์ที่ถูกต้อง ภายใน dir1-dir4 ofcourse หากไม่ใช่ dir1-dir4 คุณต้องเปลี่ยนเป็นชื่อเฉพาะโดยใช้สีแดง \ | blue \ | green \ | ฯลฯ ..
alpha_989

4. พิมพ์ผิด .. ฉันใช้ [a-z0-9] * ก่อน .. จากนั้นฉันก็รู้ว่า [^ /] * สั้นลงและครอบคลุมยิ่งขึ้น .. เพื่อเปลี่ยนมันเมื่อฉันโพสต์ข้อความนี้ ขอบคุณสำหรับความคิดเห็นของคุณอย่างระมัดระวัง
alpha_989

0

ฉันรู้ว่าคุณระบุว่าใช้ find แต่เพื่อแสดงตัวเลือกอื่น ๆ ที่สามารถใช้ได้คุณสามารถใช้ xargs:

find . -type d | grep -E "dir1$|dir2$" | xargs ls  

find . -name "dir1" -or -name "dir2" | xargs ls

คุณสามารถมีไฟล์ชื่อ "โฟลเดอร์" ที่มีลักษณะดังนี้:

$ cat folders
dir1
dir2
dir3
dir4

จากนั้นคุณสามารถทำสิ่งนี้:

$ cat folders | xargs -I % find . -type d -name % | xargs ls
./Documents/dir1:
file1  file2  file3  file4

./Documents/dir2:
file1  file2  file3  file4

./Documents/dir3:
file1  file2  file3  file4

./Documents/dir4:
file1  file2  file3  file4

xargs ในความคิดของฉันฉันรู้สึกหลากหลายมากกว่าค้นหา -exec นอกจากนี้คุณสามารถทำสิ่งที่บ้าคลั่งเช่น

$ cat << EOF | xargs -I {} find ~ -name "{}" | xargs ls
> dir1
> dir2
> dir3
> EOF
/home/user/Documents/dir1:
file1  file2  file3  file4

/home/user/Documents/dir2:
file1  file2  file3  file4

/home/user/Documents/dir3:
file1  file2  file3  file4
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.