วิธีแสดงรายการไฟล์ที่ไม่มีไดเรกทอรีและกรองตามชื่อ (ตัวเลือก ls)


42

uploadsฉันมีไดเรกทอรีที่เรียกว่า มันมีไฟล์จำนวนมากรวมถึงไดเรกทอรีย่อยบางแห่งที่มีไฟล์อยู่ด้วย

มีวิธีที่ฉันสามารถ (ในขั้นตอนเดียว) ทำต่อไปนี้:

  1. แสดงรายการเฉพาะไฟล์ในไดเรกทอรีที่อัปโหลดราก - ฉันไม่ต้องการเห็นชื่อโฟลเดอร์ย่อยหรือเนื้อหาของพวกเขา

    และ

  2. อย่าแสดงไฟล์ใด ๆ ที่ขึ้นต้นด้วย t_

ฉันรู้เกี่ยวกับ-dธง แต่มันก็ไม่ได้รับสิ่งที่ฉันต้องการ

คำตอบ:


53

findเสียงเหมือนงานสำหรับ

  • ใช้-maxdepthเพื่อส่งคืนไดเรกทอรีปัจจุบันเท่านั้นไม่ใช่ค้นหาซ้ำภายในโฟลเดอร์ย่อย
  • ใช้-type fเพื่อส่งคืนไฟล์เท่านั้นไม่ใช่ไดเร็กทอรีหรือโหนดอุปกรณ์หรืออย่างอื่น
  • ใช้การรวมกันหาก-notและ-nameเพื่อหลีกเลี่ยงไฟล์ที่มีชื่อที่คุณไม่ต้องการ

มันอาจมารวมกันเช่นนี้

find /path/to/uploads -maxdepth 1 -type f -not -name 't_*'

ขอบคุณ! ฉันค่อนข้างใหม่กับ CLI และไม่เคยใช้มาก่อน ฉันจะตรวจสอบเพิ่มเติมอย่างแน่นอน
EmmyS

2
@EmmyS: คุณอาจพบว่ามีเคล็ดลับอีกเล็กน้อยที่เป็นประโยชน์ได้ที่นี่ @Gilles พูดถึงการใช้-exec ls -lG -- {} +ในคำตอบของเขาเพื่อให้ได้ผลลัพธ์โดยใช้ตัวเลือกพิเศษเพื่อ ls นอกจากนี้คุณยังสามารถเพิ่มการ-lsค้นหานี้เพื่อรับมุมมองที่ละเอียดของ ls ที่รวดเร็วและสกปรก
คาเลบ

18

GNU ls (เช่นคำสั่ง ls ในระบบ Linux ที่ไม่ได้ฝังตัวและ Cygwin มีอยู่ใน unices อื่น ๆ ) มีตัวเลือกในการซ่อนไฟล์บางไฟล์ตามชื่อของมัน ไม่มีวิธีที่จะเพิกเฉยต่อไดเรกทอรี

ls --hide='t_*' uploads

อีกวิธีคือการทำให้เปลือกของคุณทำการจับคู่ Bash, ksh และ zsh มีรูปแบบการปฏิเสธ!(t_*)เพื่อจับคู่ไฟล์ทั้งหมดยกเว้นที่ตรงกันt*; ในทุบตีคุณลักษณะนี้จะต้องเปิดด้วยshopt -s extglobและใน zsh setopt ksh_globจะต้องมีการเปิดใช้งานด้วย zsh ยังมีไวยากรณ์เทียบเท่าที่จะต้องเปิดด้วย^t_* setopt extended_globนี่ยังไม่ละเว้นไดเรกทอรี zsh มีคุณสมบัติพิเศษที่ช่วยให้เพื่อให้ตรงกับไฟล์โดยไม่เพียง แต่ชื่อ แต่ยังตามข้อมูลเมตาและอื่น ๆ : บ่น glob เพิ่ม(.)เมื่อสิ้นสุดการแข่งขันเพื่อ จำกัด ไฟล์ปกติ การปฏิเสธ^เป็นส่วนหนึ่งของไวยากรณ์การจับคู่ชื่อดังนั้น^t_*(.)หมายถึง“ ไฟล์ปกติทั้งหมดไม่ตรงกันt_*” และไม่ใช่“ ไฟล์ทั้งหมดที่ไม่ตรงกับไฟล์ปกติt_*

setopt extended_glob  # put this in your ~/.zshrc
ls uploads/^t_*(.)

หากคุณพบว่าตัวเองไม่มีเครื่องมือขั้นสูงคุณสามารถทำเช่นนี้ในยูนิกซ์ใด ๆ findกับ มันไม่ใช่สิ่งที่คุณมักจะพิมพ์บนบรรทัดคำสั่ง แต่มันทรงพลังและแม่นยำ คาเลบได้แสดงให้เห็นแล้วว่าการทำเช่นนี้กับ GNU หา -maxdepthตัวเลือกที่ไม่ได้เป็นแบบพกพา คุณสามารถใช้-pruneแทนเพื่อหยุดการfindเรียกซ้ำ

find uploads/* -type d -prune -o \! -type f -name 't_*' -print

แทนที่-printด้วย-exec ls -lG -- {} +เพื่อดำเนินการlsด้วยตัวเลือกที่คุณชื่นชอบในไฟล์

คำสั่งทั้งหมดข้างต้นซ่อนไฟล์ dot (เช่นไฟล์ที่ชื่อขึ้นต้นด้วย a .) หากคุณต้องการที่จะแสดงพวกเขาผ่าน-Aไปlsหรือเพิ่มDรอบคัดเลือกรอบตัวเป็น zsh ( ls uploads/^t_*(.D)) ด้วยfindคุณสามารถใช้วิธีการที่แตกต่างกันของการทำให้ recurse ระดับหนึ่งเท่านั้น ( findไม่ไฟล์ dot ไม่รักษาเป็นพิเศษ) สิ่งนี้ใช้ได้ผลก็ต่อเมื่อคุณเรียกใช้findในไดเรกทอรีปัจจุบัน

cd uploads && find . -name . -o -type d -prune -o \! -type f -name 't_*' -print

3
คุณมี dayjob ไหม? ;-) ฉันประหลาดใจอย่างต่อเนื่องที่ความยาวและระดับของรายละเอียดคำตอบของคุณแม้แต่คำถามที่ดูง่ายที่สุดที่นี่ที่ Unix SE! .. ติดตามต่อไป! :)
alex

ขอบคุณ! รายละเอียดยอดเยี่ยม ฉันไม่รู้ว่าฉันมี "เครื่องมือขั้นสูง" หรือไม่ในตอนนี้ ฉันใช้ Mac ในที่ทำงาน (แม้ว่า Linux ที่บ้านดังนั้นฉันมั่นใจว่ามันจะมีประโยชน์ในบางจุด)
EmmyS

@EmmyS: สำหรับกล่อง linux ของคุณฉัน-maxdepthควรใช้งานได้ แต่ปัญหา "การพกพา" Gilles อ้างถึงคือ BSD find(หรือที่พบใน OSX ฉันคิดว่า) เป็นสัตว์ที่แตกต่างกันเล็กน้อยดังนั้นคุณอาจต้องการคำตอบของเขาด้วย @Gilles: +1 สำหรับเคล็ดลับ zsh!
คาเลบ

1
@Gilles: บางความเห็นที่ไม่ได้ฉ่ำความคิดเกี่ยวกับpruneการนึกถึง แต่ฉันจะปล่อยให้มันพูดง่ายๆว่าเมื่อฉันล้อเล่นในระบบของฉันเองจำนวนครั้งที่ความคิด " คำสั่งนี้จะทำงานถ้าฉันอยู่ AIX, Solaris หรือ Minix3 "จะอยู่ที่ประมาณ ... สแตนด์บาย ... ฉันมีช่วงเวลาที่ยากลำบากได้รับการอ่านเมตร ... 0.00การแสดงผลที่ถูกแช่แข็งด้วย
Caleb

2
Gnu lsไม่มี--use-telepathyตัวเลือกหรือไม่? นี่เป็นวิธีที่รวดเร็วที่สุดในการแสดงไฟล์ที่คุณต้องการ มันอาจจะไม่สามารถพกพาได้
dubiousjim

8
ls -l /folder | grep ^- | awk '{print $9}'

คืออะไร$9ในคำสั่งนี้?
EmmyS

3
@EmmyS หมายถึงฟิลด์ / คอลัมน์ที่ 9 ของเอาต์พุต คำตอบนี้พยายามที่จะแยกlsเอาท์พุท
jw013

print $ NF` จะดีกว่า IMO $ NF หมายถึงจำนวนเขตข้อมูลซึ่งจะเป็น 9 และเป็นการใช้งานทั่วไปใน AWK ซึ่งเป็นโอกาสที่ดีในการสอนผู้อื่นเกี่ยวกับ $ NF
Elijah Lynn

1
ls -l | grep -v ^d | grep name$

สิ่งใดที่ทำให้โซลูชันนี้ (ซึ่งต้องใช้หลายคำสั่งและไพพ์) ควรใช้find?
HalosGhost

มันกระชับอ่านง่ายและอยู่กับระเบียบคำสั่ง ls ฉันพบว่าจดจำได้ง่ายกว่าข้อโต้แย้งคำสั่ง find แต่ละตัวของพวกเขาและรุ่งโรจน์สำหรับตัวเลือก!
tkjef

0

ให้ฉันใช้ shot lsและไปป์:

ls  -l --hide='t_*'  uploads/ | grep -v ^d | tr -s ' ' | cut -d ' ' -f 9

พูดคอลัมน์สุดท้ายคือคอลัมน์ที่ 9


1
เกิดอะไรขึ้นถ้ามีไฟล์ที่มีช่องว่าง
จอร์แดน

0

หากปัญหาการพกพา -maxdepth ของ find เป็นเรื่องที่น่ากังวลคุณสามารถใช้:

ls -l uploads/ | awk '/^-/ && $9 !~/^t_/ {print $9}'

ฉันไม่ใช่ผู้เชี่ยวชาญ แต่ฉันคิดว่านี่น่าจะใช้ได้ ฉันคิดว่ามันดูเป็นความลับเล็ก ๆ น้อย ๆ แต่ถ้าคุณพูด awk มันไม่ได้จริงๆ สามารถใช้ $ NF แทน $ 9 ได้ คุณสามารถทำได้:

ls -l uploads/ | awk '/^-/' | awk '!/^t_/ {print $9}'

ซึ่งทำสิ่งเดียวกัน (แต่อาจมีประสิทธิภาพน้อยกว่าแบบเดิม)

จริงๆแล้วหลังจากคิดเกี่ยวกับการโพสต์อื่น ๆ ดูเหมือนว่า

ls -l --hide=t_* uploads/ | awk '/^-/ {print $9}'

เป็นวิธีที่สั้นลงและชัดเจนยิ่งขึ้น

มีคนโปรดแก้ไขฉันถ้าฉันผิด :-)


แยกวิเคราะห์lsโดยทั่วไปไม่ได้เป็นความคิดที่ดี เทคนิค awk ของคุณจะล้มเหลวด้วยชื่อไฟล์ที่มีช่องว่างในนั้น
Mat

@mat - ขอบคุณสำหรับการแก้ไข หลังจากอ่านบทความที่คุณ (และ jw013) ชี้ให้เห็นฉันเห็นว่าlsไม่สามารถเชื่อถือได้ในการส่งออกชื่อไฟล์ที่ถูกต้อง แม้ว่าฉันจะต้องเขียนรหัส awk ใหม่เพื่อพิมพ์ทุกอย่างตั้งแต่ $ 9 ถึงจุดสิ้นสุดของบรรทัด (เพื่อรวม whitespaces) ผลลัพธ์lsนี้อาจยังคงผิดพลาด สิ่งนี้น่าผิดหวังและควรได้รับการแก้ไข IMO ขอบคุณอีกครั้ง.
kkaszub


-1

ลองใช้นามแฝงนี้แล้วใช้:

alias l='ls -hLlF'

ls -hLlFt_ไม่แสดงไดเรกทอรีย่อยและมันไม่แสดงไฟล์ที่เริ่มต้นด้วย ดังนั้นวิธีนี้ตอบคำถามได้อย่างไร
Raphael Ahrens

บางทีฉันอาจเข้าใจผิดคำถาม ls -hLlF จะไม่แสดงไดเรกทอรีเป้าหมายของไดเรกทอรีที่เชื่อมโยง
Granular

น่าจะเป็นแบบนั้น. แต่คุณยังไม่ได้อ่านคำตอบอื่น ๆ สำหรับคำถาม?
Raphael Ahrens

-1

peasy ง่าย ๆ :

ls -l --hide 't_*' <absolute path to desired directory> | grep -v ^d


(1) คำตอบนี้ง่ายมากมันได้รับมาก่อน (2) ทำไมคุณเชื่อว่าคุณต้องระบุเส้นทางแบบเต็มไปยังไดเรกทอรี?
Scott

@Scott - นี่เป็นวิธีที่ง่ายและรวดเร็วในการหาทางออก เส้นทางแบบเต็มถูกระบุเพื่อให้คำตอบสากล ...
ขุด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.