การนับจำนวนไดเร็กทอรีในไดเร็กทอรีเฉพาะ


103

วิธีนับจำนวนโฟลเดอร์ในไดเร็กทอรีเฉพาะ ฉันใช้คำสั่งต่อไปนี้ แต่จะมีคำสั่งพิเศษเสมอ

find /directory/ -maxdepth 1 -type d -print| wc -l

ตัวอย่างเช่นถ้าฉันมี 3 โฟลเดอร์คำสั่งนี้จะให้ 4. ถ้ามี 5 โฟลเดอร์คำสั่งจะมี 6 ทำไม?


4
การนับ 1 เพิ่มเติมนั้นเกิดจากไดเร็กทอรีปัจจุบัน "." ซึ่งนำมาพิจารณาโดย 'find' ด้วย
patel deven

คำตอบ:


94

find กำลังพิมพ์ไดเร็กทอรีด้วย:

$ find .vim/ -maxdepth 1 -type d
.vim/
.vim/indent
.vim/colors
.vim/doc
.vim/after
.vim/autoload
.vim/compiler
.vim/plugin
.vim/syntax
.vim/ftplugin
.vim/bundle
.vim/ftdetect

คุณสามารถทดสอบชายน์ของไดเร็กทอรีแทนได้และอย่าลงมาเลย:

$ find .vim/* -maxdepth 0 -type d
.vim/after
.vim/autoload
.vim/bundle
.vim/colors
.vim/compiler
.vim/doc
.vim/ftdetect
.vim/ftplugin
.vim/indent
.vim/plugin
.vim/syntax

$ find .vim/* -maxdepth 0 -type d | wc -l
11
$ find .vim/ -maxdepth 1 -type d | wc -l
12

คุณยังสามารถใช้ls:

$ ls -l .vim | grep -c ^d
11


$ ls -l .vim
total 52
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
-rw-rw-r--  1 anossovp anossovp   48 Aug 29  2012 filetype.vim
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
-rw-rw-r--  1 anossovp anossovp 2505 Aug 29  2012 README.rst
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax

$ ls -l .vim | grep ^d
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax

ดี! คุณจะทำอย่างไร$ ls -l .vimกับ PHP? หรือวิธีรับเฉพาะยอดรวมโดยไม่มีรายการ ฉันหมายความว่าในกรณีนี้รับเท่านั้น52?
Pathros

ฮะ. ฉันชอบที่การโต้แย้งกับ PowerShell คือ BASH นั้นง่ายกว่าในทุก ๆ ด้าน ... ต้องการเห็นคำสั่ง POSH เพื่อทำสิ่งนี้หรือไม่? (ls).Count
Kolob Canyon

@Pathros ใช้glob ที่มี flag GLOB_ONLYDIR และนับ () ผลลัพธ์
Pilipe

1
ls -l | grep -c ^dตายง่ายและใช้ได้ผล @Pathros มีวิธีที่ดีกว่าใน PHP แต่ในกรณีที่แย่ที่สุดใน PHP คุณสามารถใช้ฟังก์ชัน shell_exec () เพื่อดำเนินการบรรทัดคำสั่งและส่งคืนผลลัพธ์เป็นสตริงได้ คือ $dirCount = shell_exec('ls -l | grep -c ^d');
กิกะไบต์

66

รับจำนวนเฉพาะไดเร็กทอรีในไดเร็กทอรีปัจจุบัน

echo */ | wc

คุณจะได้รับความนิยม 1 309 4594

2nd digitแสดงถึงไม่ ของไดเรกทอรี

หรือ

tree -L 1 | tail -1


8
สิ่งนี้จะล้มเหลวหากมีช่องว่างในชื่อผบ.
Michael Campbell

zsh: no matches found: */ต้องการ nullglob
Anne van Rossum

@AnnevanRossum คุณมีecho. typewhich echo
EmptyData

7
อันแรกสามารถปรับปรุงเพิ่มเติมได้เล็กน้อย:echo */ | wc -w
ibic

ไม่ใช่ว่าสิ่งนี้จะนับ 1 ถ้าไม่มีไดเรกทอรีแทนที่จะเป็น 0
jinawee

27
find . -mindepth 1 -maxdepth 1 -type d | wc -l

สำหรับการค้นหา-mindepthหมายถึงจำนวนทั้งหมดที่เรียกซ้ำในไดเรกทอรี

-maxdepth หมายถึงจำนวนรวมในไดเรกทอรี

-type d หมายถึงไดเรกทอรี

และสำหรับwc -lวิธีการนับบรรทัดของอินพุต


2
คุณช่วยอธิบายคำตอบของคุณได้ไหม (ภายในคำตอบของคุณ)
Zulu

-mindepth หมายถึงจำนวนทั้งหมดที่เรียกคืนในไดเร็กทอรี -maxdepth หมายถึงจำนวนรวมในไดเร็กทอรี -type d หมายถึงไดเร็กทอรีและ wc -l หมายถึงจำนวนบรรทัดจากรายการไดเร็กทอรีที่ระบุ
shiyani suresh

find . -mindepth 1 -maxdepth 1 -type d | wc -lจะทำให้คุณมีช่องว่างระหว่างจำนวนมากตัวอย่างเช่น:“ 2“ คุณสามารถป้องกันได้โดยใช้สิ่งนี้: dir_count=`find . -maxdepth 1 -type d | wc -l | xargs`; echo $dir_count # will print just 2 และอาจมีประโยชน์สำหรับเงื่อนไขต่างๆเช่นif (( $dir_count > 1 )); then echo "Yaa"; fi # will print "Yaa"
naorz

16

หากคุณมีไดเร็กทอรีในโฟลเดอร์และไม่มีไฟล์ให้ทำดังนี้

ls | wc -l

2
สิ่งนี้ได้รับไฟล์ด้วย แต่คำถามเกี่ยวกับโฟลเดอร์ / ไดเรกทอรี
Robert

12

วิธีที่ดีที่สุดในการนำทางไปยังไดรฟ์ของคุณและดำเนินการ

ls -lR | grep ^d | wc -l

และเพื่อค้นหาโฟลเดอร์ทั้งหมดรวมถึงไดเรกทอรีย่อย?

find /mount/point -type d | wc -l

... หรือค้นหาโฟลเดอร์ทั้งหมดในไดเร็กทอรีรูท (ไม่รวมไดเร็กทอรีย่อย)?

find /mount/point -maxdepth 1 -type d | wc -l

ไชโย!


โปรดสังเกตว่า ls ก่อนหน้านี้-lRละเว้นไดเร็กทอรีคำนำหน้า dot ในขณะที่find -type d นับดังนั้นการนับที่กำหนดโดยคำสั่งแรกจะผิดหากคุณมีไดเร็กทอรีที่นำหน้า dot (ตัวอย่างเช่นคุณมีไดเร็กทอรีย่อย. git!) คุณไม่สามารถใช้เพียง -lRaเพราะคุณได้รับสำหรับแต่ละไดเรกทอรี.และ..รายการ นอกจากนี้ยังใช้กับคำตอบของ @Pavel Anossov
marcz

12

เรียกใช้stat -c %h folderและลบ 2 ออกจากผลลัพธ์ สิ่งนี้ใช้กระบวนการย่อยเดียวเท่านั้นเมื่อเทียบกับ 2 (หรือ 3) ที่ต้องการโดยโซลูชันอื่น ๆ ส่วนใหญ่ที่นี่ (โดยทั่วไปจะเป็นfindบวกwc)

ใช้ sh / bash:

cnt = $ ((`stat -c% h โฟลเดอร์` - 2))
echo $ cnt # 'echo' คือ sh / bash builtin ไม่ใช่กระบวนการเพิ่มเติม

ใช้ csh / tcsh:

@ cnt = `stat -c% h โฟลเดอร์` - 2
echo $ cnt # 'echo' เป็น csh / tcsh builtin ไม่ใช่กระบวนการเพิ่มเติม


คำอธิบาย: stat -c %h folderพิมพ์จำนวน hardlinks ไปยังโฟลเดอร์และแต่ละโฟลเดอร์ย่อยภายใต้โฟลเดอร์มี ../ รายการซึ่งเป็น Hardlink กลับไปยังโฟลเดอร์ คุณต้องลบ 2 เนื่องจากมีฮาร์ดลิงก์เพิ่มเติมอีกสองรายการในการนับ:

  1. โฟลเดอร์อ้างอิงตนเอง. / รายการและ
  2. โฟลเดอร์การเชื่อมโยงของผู้ปกครองที่จะโฟลเดอร์

ที่เกี่ยวข้องกับคำถามนี้: [ทำไมไดเร็กทอรีใหม่จึงมีฮาร์ดลิงก์นับ 2 ก่อนที่จะเพิ่มอะไรเข้าไป? ] ( unix.stackexchange.com/questions/101515 ) อธิบายว่าเหตุใดจึงเป็นคำตอบที่ดีเยี่ยม น่าเสียดายที่สิ่งนี้ไม่ได้รับความสนใจมากพอ! แม้ว่าจะเป็นคำตอบที่ดี แต่ผลลัพธ์ของมันขึ้นอยู่กับระบบไฟล์ แต่สำหรับระบบไฟล์ทั่วไปส่วนใหญ่สิ่งนี้จะได้ผล
kvantour

8

ฉันคิดว่าง่ายที่สุดคือ

  ls -ld images/* | wc -l

imagesไดเร็กทอรีเป้าหมายของคุณอยู่ที่ไหน ขีด จำกัด แฟล็ก -d สำหรับไดเร็กทอรีและแฟล็ก -l จะดำเนินการแสดงรายการต่อบรรทัดซึ่งเข้ากันได้กับwc -lจำนวนบรรทัดที่คุ้นเคย


ส่งคืนผลลัพธ์ +1 ด้วย
josef

1
ตามman ls, -dไม่: "ไดเรกทอรีรายชื่อตัวเองไม่ได้เนื้อหาของพวกเขา" คือว่าถ้าคุณทำงานls /tmpคุณจะได้รับสิ่งที่อยู่ใน/tmpและถ้าคุณเรียกคุณเพิ่งได้รับls -d /tmp สวิทช์ไม่ได้กรองไดเรกทอรีเป็นที่ถามหา /tmp-d
Robert

5

ตัวอย่างที่เป็นประโยชน์:

นับไฟล์ในผบ. ปัจจุบัน

/bin/ls -lA  | egrep -c '^-'

นับ dirs ในผบ. ปัจจุบัน

/bin/ls -lA  | egrep -c '^d'

นับไฟล์และ dirs ใน dir ปัจจุบัน

/bin/ls -lA  | egrep -c '^-|^d'

นับไฟล์และ dirs ในไดเร็กทอรีย่อยเดียว

/bin/ls -lA  subdir_name/ | egrep -c '^-|^d'

ฉันสังเกตเห็นสิ่งแปลก ๆ (อย่างน้อยก็ในกรณีของฉัน):

เมื่อผมได้ลองกับlsแทนพารามิเตอร์ไม่ทำงานตามที่ espected เมื่อฉันใช้การ แสดงนั้น. / และ ../ ผลลัพธ์นั้นนับผิด วิธีแก้ปัญหา: แทน/bin/ls-Ado not list implied . and ..ls/bin/lsls


4

ไม่มีไดเรกทอรีที่เราสามารถค้นหาได้โดยใช้คำสั่งด้านล่าง

ls -l | grep "^d" | wc -l


แค่ls -l | grep ^d | wc -lจะทำไม่จำเป็นต้องใช้"ที่นี่
kaspiotr

3

วิธีแก้ปัญหาการทุบตีที่บริสุทธิ์:

shopt -s nullglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} (non-hidden) directories"

หากคุณต้องการนับไดเรกทอรีที่ซ่อนอยู่:

shopt -s nullglob dotglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} directories (including hidden ones)"

โปรดทราบว่าสิ่งนี้จะนับลิงก์ไปยังไดเรกทอรีด้วย หากคุณไม่ต้องการสิ่งนั้นก็ยากขึ้นเล็กน้อยด้วยวิธีนี้


ใช้find:

find /path/to/directory -type d \! -name . -prune -exec printf x \; | wc -c

เคล็ดลับคือการส่งออกเป็นxstdout ทุกครั้งที่พบไดเร็กทอรีจากนั้นใช้wcเพื่อนับจำนวนอักขระ ซึ่งจะนับจำนวนไดเรกทอรีทั้งหมด (รวมถึงไดเรกทอรีที่ซ่อนอยู่) โดยไม่รวมลิงก์


วิธีการที่นำเสนอในที่นี้คือการเขียนอักขระตลก ๆ ที่ปลอดภัยซึ่งสามารถปรากฏในชื่อไฟล์ได้ (เว้นวรรคบรรทัดใหม่อักขระลูกโลก ฯลฯ )


นี่เป็นทางออกที่ดีที่สุดที่นำเสนอในคำถามนี้และจะใช้ได้ผลเสมอ!
kvantour

3

ใช้zsh:

a=(*(/N)); echo ${#a}

Nเป็น nullglob ที่/ทำให้มันตรงกับไดเรกทอรี#นับ มันจะจัดการกับช่องว่างในชื่อไดเร็กทอรีอย่างเรียบร้อยรวมทั้งส่งคืน0หากไม่มีไดเร็กทอรี


0

นับไฟล์และโฟลเดอร์ย่อยทั้งหมดสไตล์ windows:

dir=/YOUR/PATH;f=$(find $dir -type f | wc -l); d=$(find $dir -mindepth 1 -type d | wc -l); echo "$f Files, $d Folders"

0

หากคุณต้องการใช้นิพจน์ทั่วไปให้ลอง:

ls -c | grep "^d" | wc -l

1
คุณต้องการเพิ่มคำอธิบายให้กับคำตอบแบบใช้รหัสเท่านั้นหรือไม่? มันจะช่วยต่อสู้กับความเข้าใจผิดที่ว่า StackOverflow เป็นบริการเขียนโค้ดฟรี ดูที่นี่เพื่อปรับปรุงรูปลักษณ์: stackoverflow.com/editing-help
Yunnosch

0

คำตอบที่ดีที่สุดสำหรับสิ่งที่คุณต้องการคือ

echo `find . -maxdepth 1 -type d | wc -l`-1 | bc

สิ่งนี้จะลบหนึ่งตัวเพื่อลบ "." ที่ไม่ต้องการออก ไดเร็กทอรีที่ค้นหารายการ (ตามที่ patel deven กล่าวไว้ข้างต้น)

หากคุณต้องการนับโฟลเดอร์ย่อยแบบวนซ้ำให้ออกจากตัวเลือก maxdepth ดังนั้น

echo `find . -type d | wc -l`-1 | bc

ป.ล. หากคุณพบว่าการแทนที่คำสั่งนั้นน่าเกลียดการลบคำสั่งนั้นสามารถทำได้โดยใช้sedและbc.

การลบหนึ่งจากจำนวน:

find . -maxdepth 1 -type d | wc -l | sed 's/$/-1\n/' | bc

หรือเพิ่มจำนวนเพื่อลบหนึ่ง:

find . -maxdepth 1 -type d | wc -l | sed 's/^/-1+/' | bc

-1

วิธีที่ดีที่สุด:

ls -la | grep -v total | wc -l

สิ่งนี้ช่วยให้คุณนับได้อย่างสมบูรณ์แบบ


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