คำสั่ง 'ls -d' ไม่แสดงไดเรกทอรี มีวิธีรับ 'ls' เพื่อแสดงเฉพาะไดเรกทอรีแทนไฟล์และไดเรกทอรีหรือไม่


44

มีวิธีการที่lsจะแสดงเฉพาะไดเรกทอรีแทนไฟล์และไดเรกทอรีหรือไม่

จากหน้าคน:

   -d, --directory
          list directory entries instead of contents, and do not  derefer
          ence symbolic links

ดังนั้นหากฉันพิมพ์ที่/ไดเรกทอรีฉันคาดว่าจะเห็นไดเรกทอรีเท่านั้น มันแสดงว่า "." แทน

$ cd /
$ ls -d
.

ฉันคาดหวังว่าls -dจะแสดงสิ่งนี้ให้ฉัน:

$ ls -d
bin    data  home        opt    sbin  sys      var
boot   dev   lib         media  proc  selinux  tmp
cdrom  etc   lost+found  mnt    root  srv      usr

มีวิธีการที่lsจะแสดงเฉพาะไดเรกทอรีแทนไฟล์และไดเรกทอรีหรือไม่


17
lsd อาจสร้างความสับสนได้มาก
boehj

2
@jin ls -d * / ทำงาน แต่ทำไมฉันต้อง "* /" เพื่อให้ได้สิ่งที่ฉันต้องการ
nelaaro

8
@nelaar -dไม่ได้หมายถึงรายการไดเรกทอรีเท่านั้นมันหมายถึงการไม่แสดงรายการเนื้อหาไดเรกทอรี ลองพิมพ์ls */แล้วคุณจะเห็นเนื้อหาของไดเรกทอรีทั้งหมด
จิน

2
ฉันได้ldiralised ไปls -d */ในของฉัน.bashrcจะทำให้เรื่องนี้ง่ายขึ้น ...
KennyPeanuts

1
ls สามารถให้ข้อมูลได้มากมาย แต่ไม่ใช่เพียงแฟ
ล็

คำตอบ:


50

ความคาดหวังของคุณขึ้นอยู่กับ DOS Think / Windows Think และผิด บน MS-DOS, Windows, และระบบปฏิบัติการ IBM / Microsoft อื่น ๆ , การขยายไวด์การ์ดจะทำโดยคำสั่งเอง, และสิ่งต่าง ๆ เช่น/aตัวเลือกของdirคำสั่งจะทำหน้าที่เป็นตัวกรองแอ็ตทริบิวต์ระหว่างการขยายไวด์การ์ด dirขยาย wildcards เช่น*ซึ่งตัวแปลคำสั่งส่งผ่านไปตามที่เป็นอยู่และหาก/aมีการระบุจะใช้ตัวกรองที่เหมาะสมกับสิ่งที่ถูกส่งคืน (ในบางระบบปฏิบัติการตัวกรองแอ็ตทริบิวต์สามารถกำหนดให้กับการเรียกระบบสำหรับการแจงนับไดเรกทอรีและเคอร์เนลระบบปฏิบัติการหรือไดรเวอร์ระบบไฟล์ของมัน

บน Unices และบน Linux การขยาย wildcard จะดำเนินการโดยเชลล์และไม่อนุญาตให้ใช้สิทธิ์ คุณทำในรูทไดเร็กทอรีเมื่อใด

ls *

สิ่งที่lsคำสั่งเองได้รับจากเชลล์คืออะไร (คล้าย)

ls bin home opt var boot dev tmp ฯลฯ หายไป + พบ root usr

สิ่งที่-d/ --directoryตัวเลือกไม่ถูกปิดสิ่งที่เกิดขึ้นตามปกติต่อไป สิ่งที่เกิดขึ้นตามปกติถัดไปคือlsดูที่อาร์กิวเมนต์แต่ละตัวแล้วเห็นว่าพวกมันเป็นไดเรกทอรีและตัดสินใจที่จะแจกแจงเนื้อหา สำหรับอาร์กิวเมนต์ที่ชื่อไฟล์มันพิมพ์ข้อมูลสำหรับตัวไฟล์เอง ด้วย-dตัวเลือกไดเรกทอรีจะได้รับการปฏิบัติเหมือนไฟล์ ดังนั้นlsพิมพ์ข้อมูลสำหรับแต่ละไดเรกทอรีที่ส่งผ่านเป็นอาร์กิวเมนต์เช่นเดียวกับที่ทำถ้าเป็นไฟล์

ดังนั้นจึง-d ไม่ใช่ตัวเลือก "พิมพ์เฉพาะไดเรกทอรี" ในความเป็นจริงไม่เพียง แต่จะไม่มีตัวเลือกดังกล่าว มีไม่สามารถเป็นตัวเลือกดังกล่าว การขยายตัวของ Wildcard นั้นทำโดยเชลล์และ (ใน POSIX shอย่างน้อย) ไม่มีวิธีที่จะบอกเชลล์ให้ตรวจสอบการอนุญาตและบิตประเภทไฟล์เมื่อมันขยาย*เข้าไปในรายการชื่อ ที่จะได้รับรายชื่อของไดเรกทอรีเพียงอย่างเดียวก็เป็นสิ่งที่จำเป็นอย่างใดอย่างหนึ่งที่จะใช้findคำสั่งตามที่อธิบายไว้โดยztank1013หรือเพื่อใช้เคล็ดลับที่ชื่อพา ธ ที่ลงท้ายด้วยการเฉือนหมายถึงรายการไดเรกทอรีตามที่อธิบายไว้โดย. Jin( Jinเล่ห์เหลี่ยมของมันจบลงด้วยlsคำสั่งที่รับอาร์กิวเมนต์

ls bin / home / opt / var / boot / dev / tmp / etc / lost + found / root / usr /

เนื่องจากรูปแบบ*/นั้นเป็นจริงในการจับคู่ชื่อพา ธ ที่มีสององค์ประกอบส่วนที่สองว่างเปล่าและดังนั้นจึงไม่ค่อยทำสิ่งที่ต้องการ โดยเฉพาะอย่างยิ่งมันจะจัดการลิงก์สัญลักษณ์ที่ชี้ไปยังไดเรกทอรีราวกับว่าเป็นไดเรกทอรี)

พฤติกรรมของการls -dไม่มี*เป็นส่วนขยายที่ง่ายของข้างต้น หนึ่งก็มีที่จะรู้ว่าสิ่งหนึ่งที่เพิ่มเติมเกี่ยวกับls: .เมื่อมันจะได้รับการขัดแย้งใดจะอนุมานว่าอาร์กิวเมนต์เริ่มต้นของ ตอนนี้ได้โดยไม่ต้อง-dตัวเลือกพฤติกรรมดังกล่าวจะนำไปสู่เนื้อหาของไดเรกทอรีชื่อโดย.การระบุและข้อมูลสำหรับเนื้อหาที่แสดง ด้วย-dตัวเลือกไดเรกทอรี.ได้รับการปฏิบัติเช่นเดียวกับถ้ามันเป็นไฟล์และข้อมูลของตัวเองจะปรากฏมากกว่าเนื้อหาแจกแจง


3
" ไม่มีตัวเลือกดังกล่าว" - นั่นเป็นคำสั่งที่ค่อนข้างแข็งแกร่ง - การใช้งานตัวเลือกดังกล่าวชัดเจน: ดูอาร์กิวเมนต์ที่ไม่ใช่ไดเรกทอรีและไม่สนใจ สิ่งที่ไม่สามารถนำมาใช้ได้นั้นมีค่าเท่ากับdir /s *.txt[โดยไม่ต้องใช้การอ้างถึงไวลด์การ์ดเพื่อหา]
Random832

6
ถูกต้อง แต่ไม่มีเหตุผลเชิงตรรกะ ls ไม่สามารถมีตัวเลือกที่จะกรองรายการที่ถูกส่งผ่านเป็นอาร์กิวเมนต์ ความจริงที่ว่า "การขยายตัวสัญลักษณ์แทนหย่าขาดจากประเภทรายการตรวจสอบ" เป็นที่ไม่เกี่ยวข้องตั้งแต่นี้มีอะไรที่ทุกคนจะทำอย่างไรกับการขยายตัวสัญลักษณ์แทน - เพียงประเภทรายการตรวจสอบซึ่งมีเหตุผลที่มันไม่สามารถทำได้ไม่มีสิ้นเชิงภายใน LS ถ้า ls --color สามารถแรเงาสีฟ้าได้ ls -F สามารถใส่ a / after ได้และ ls -l สามารถใส่ 'd' ในโหมดจากนั้นตัวเลือกสมมุติอื่น ๆ อาจละเว้นได้ การที่ไม่มีตัวเลือกดังกล่าวไม่ได้หมายความว่า " ไม่สามารถทำได้ "
Random832

5
Random832 สร้างจุดที่เหมาะสม: ls อาจมีตัวเลือกในการกรองไฟล์หรือไดเรกทอรีและสิ่งนี้ไม่ได้เกิดขึ้นพร้อมกันกับการที่เชลล์ทำการขยาย ไม่มีเงื่อนไขการแย่งชิงภายใน ls: สามารถกรองได้ตามสถานะของไฟล์ตามปกติ (มีการแข่งขันกันระหว่างการขยายตัวของเชลล์และ ls, FWIW) ฉันคิดว่าการขยายตัวของเชลล์เป็นเพียงส่วนหนึ่งของเหตุผล: การขยายตัวของเชลล์ (และการกรองโดยทั่วไป) ไม่ได้ใช้งานใน ls เพราะจะต้องนำมาใช้อีกครั้งใน cp , mv, ฯลฯ Unix เป็น "ทำสิ่งหนึ่งและทำมันให้ดี" หากคุณต้องการการกรองขั้นสูงมีเครื่องมือสำหรับสิ่งนั้น
Thanatos

2
ls -pตัวเลือกเพิ่ม/สัญลักษณ์ไปยังไดเรกทอรีเท่านั้น ไม่มีเหตุผลที่จะไม่ขยายความสามารถในการพิมพ์ออกไปด้วยสิ่งที่ทำหน้าที่ส่งออกสิ่งเหล่านี้ (แทนที่จะls -p | grep /)
Anne van Rossum

3
@JdeBP, ad-hominem attack ("kiddo") และความเย่อหยิ่ง (ทุกคนยกเว้นคุณไม่รู้ "พื้นฐานของ Unix") ไม่ได้อยู่ในการสนทนาทางเทคนิค นอกจากนี้คุณกำลังดึงชายฟางเมื่อคุณยืนยันว่าตัวเลือกคำสั่งไม่สามารถควบคุมการขยายสัญลักษณ์แทนที่ทำโดยเชลล์ แน่นอนมันไม่สามารถ! ทั้ง Random832 หรือ Thanatos หรือ Anne van Rossum และไม่ใช่แม้แต่คำถามที่กล่าวถึงสัญลักษณ์ตัวแทนในทางใดทางหนึ่ง ข้อคัดค้านคือls --only-directories .ตัวเลือกนั้นสามารถเพิ่มเข้าไปได้lsในที่สุด
mkalkov

30

คุณสามารถใช้ls -d */หรือls -d .*/สำหรับไดเรกทอรีที่ซ่อนอยู่


เคล็ดลับที่ชาญฉลาดโดยใช้ /!
โมโน

ใช่นี่เป็นสิ่งที่ดี มีกรณีใดบ้างที่ใช้ไม่ได้?
iyrin

5
+1 สำหรับการให้คำตอบในหนึ่งบรรทัด ฉันเดาว่าคำตอบที่ยอมรับก็มีอยู่เช่นกัน
แคลคูลัสอัศวิน

คุณจะใช้มันในสคริปต์โดยไม่ต้องอยู่ในไดเรกทอรีได้อย่างไร
DimiDak

13

ลองสิ่งนี้

 find . -mindepth 1 -maxdepth 1 -type d

เพื่อรับไดเรกทอรีภายใต้ตำแหน่งปัจจุบันของคุณ


5

คุณอาจชอบ

tree -d 

ซึ่งจัดทำรายการไดเรกทอรีและไดเรกทอรีย่อยทั้งหมดอย่างประณีตด้วยภาพกราฟิกของโครงสร้างต้นไม้


3
และลึกเพียงระดับเดียวเท่านั้น:tree -dL 1
Anne van Rossum

น่าเสียดายที่คุณไม่สามารถรวมกับต้นไม้ได้มากนัก # tree -d | grep wc -l (อินพุตมาตรฐาน)
DimiDak

5

หากคุณต้องการดูไดเรกทอรีที่มีls -lตัวเลือกรายละเอียด like (ELL) เท่านั้นคุณสามารถใช้ด้านล่าง:

find -maxdepth 1 -type d -ls;

ด้านบนจะให้รายละเอียดเหมือนกับที่คุณได้รับพร้อม-lตัวเลือก


1
มันอาจจะดีกว่าถ้าใช้find -maxdepth 1 -type d -exec ls -d {} +เพื่อรับเอาต์พุตในlsรูปแบบปกติ
mkalkov

4

หากคุณต้องการทำงานให้สำเร็จให้ลองวิธีนี้:

ls -l | grep ^d

แม้ว่าเครื่องมือเดียวจะเพียงพอในสถานการณ์นี้ เส้นท่อจะคอยช่วยเหลือคุณเสมอ ฉันชอบความยืดหยุ่นใน Linux ซึ่งฉันหวังว่าคุณจะทำ


1
นี่จะกรองมากกว่าไดเรกทอรี
ocodo

2
@Slomojo สิ่งนี้จะกรองทุกอย่างยกเว้นไดเรกทอรี คุณหมายถึงอะไร?
mkalkov

ใช่คุณต้องใช้ -l (ยาว) เพื่อให้การอนุญาตมุ่งขึ้นบรรทัด "d" สำหรับไดเรกทอรี นอกจากนี้คุณยังได้รับรายชื่อ "ยาว" ของรายการไดเรกทอรีที่ดี
geoO

1

ฉันหวังว่านี่จะแก้ไขความต้องการของคุณ คำสั่งด้านล่างจะแสดงรายการไดเรกทอรีเฉพาะในเส้นทางที่กำหนด

ls -F <path> | grep /

ตัวอย่าง:

ls -F ~ | grep /
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.