ขนาดรวมของเนื้อหาของไฟล์ทั้งหมดในไดเร็กทอรี [ปิด]


103

เมื่อฉันใช้lsหรือduฉันได้รับจำนวนเนื้อที่ดิสก์ที่แต่ละไฟล์ครอบครองอยู่

ฉันต้องการผลรวมของข้อมูลทั้งหมดในไฟล์และไดเร็กทอรีย่อยที่ฉันจะได้รับถ้าฉันเปิดแต่ละไฟล์และนับจำนวนไบต์ คะแนนโบนัสหากฉันสามารถรับสิ่งนี้ได้โดยไม่ต้องเปิดแต่ละไฟล์และนับ


1
lsแสดงจำนวนไบต์ในแต่ละไฟล์ไม่ใช่จำนวนเนื้อที่ดิสก์ เพียงพอสำหรับความต้องการของคุณหรือไม่?
Greg Hewgill

3
โปรดทราบว่าduไม่สามารถใช้เพื่อตอบคำถามนี้ แสดงจำนวนเนื้อที่ดิสก์ที่ไดเร็กทอรีครอบครองบนดิสก์ (ข้อมูลของไฟล์บวกขนาดของข้อมูลเมตาของระบบไฟล์เสริม) duเอาท์พุทสามารถแม้จะมีขนาดเล็กกว่าขนาดของไฟล์ทั้งหมด สิ่งนี้อาจเกิดขึ้นหากระบบไฟล์สามารถจัดเก็บข้อมูลที่บีบอัดไว้ในดิสก์หรือหากใช้ฮาร์ดลิงก์ คำตอบที่ถูกต้องอยู่บนพื้นฐานและls findดูคำตอบของNelsonและbytepanที่นี่หรือคำตอบนี้: unix.stackexchange.com/a/471061/152606
anton_rh

คำตอบ:


108

หากคุณต้องการ 'ขนาดที่ชัดเจน' (นั่นคือจำนวนไบต์ในแต่ละไฟล์) ไม่ใช่ขนาดที่ไฟล์บนดิสก์ใช้-bหรือ--bytesตัวเลือก (หากคุณมีระบบ Linux ที่มีแกน GNU ):

% du -sbh <directory>

1
ใช้งานได้กับกล่องหมวกสีแดงรุ่นใหม่ แต่น่าเสียดายที่ไม่ได้อยู่ในกล่อง Dev ที่ฝัง
Arthur Ulfeldt

3
มีวิธีง่ายๆในการแสดง“ ขนาดที่ชัดเจน” ในรูปแบบที่มนุษย์อ่านได้หรือไม่? เมื่อใช้du -shb(ตามที่แนะนำโดยคำตอบนี้) -bดูเหมือนว่าการตั้งค่าจะแทนที่การ-hตั้งค่านั้น
Mathias Bynens

6
@MathiasBynens ย้อนกลับลำดับของแฟล็ก (เช่น du -sbh <dir>) เหมาะสำหรับฉัน
Luis E.

2
@MathiasBynensdu -sh --apparent-size /dir/
Jongosi

2
@Arkady ฉันได้ลองใช้วิธีแก้ปัญหาของคุณบน CentOS และ Ubuntu แล้วและมีข้อผิดพลาดเล็กน้อย คุณต้องการ "du -sbh" แฟล็ก "-h" ต้องอยู่หลังสุด
theJollySin

46

ใช้du -sb:

du -sb DIR

หรือเพิ่มhตัวเลือกสำหรับเอาต์พุตที่ใช้งานง่ายมากขึ้น:

du -sbh DIR

4
-b ดูเหมือนจะเป็นตัวเลือกที่ผิดกฎหมายสำหรับ MacOS 'du
lynxoid

3
@lynxoid: คุณสามารถติดตั้งรุ่น GNU brew install coreutilsกับเบียร์: gduมันจะสามารถเป็นคำสั่ง
neu242

1
ไม่ทำงาน, ไม่เป็นผล. ls-> file.gz hardlink-to-file.gz. stat -c %s file.gz-> 9657212. stat -c %s hardlink-to-file.gz-> 9657212. du -sb-> 9661308. ไม่ใช่ขนาดทั้งหมดของเนื้อหา แต่เป็นขนาดที่ไดเร็กทอรีใช้บนดิสก์
anton_rh

24

cd ไปยังไดเร็กทอรีจากนั้น:

du -sh

ftw!

เดิมเขียนเกี่ยวกับเรื่องนี้ที่นี่: https://ao.gl/get-the-total-size-of-all-the-files-in-a-directory/


1
ง่ายและได้ผล! ขอบคุณ. บางครั้งฉันต้องการเพิ่ม-Lตัวเลือกduตาม symlinks
conradkleinespel

2
ใช้ได้กับฉัน (บน OS X)
sam boosalis

2
นี่เป็นเรื่องง่ายและไม่ได้ผล พิมพ์พื้นที่ที่ไดเร็กทอรีใช้บนดิสก์ไม่ใช่ขนาดทั้งหมดของเนื้อหาที่สามารถคำนวณได้โดยการเปิดไฟล์แต่ละไฟล์และนับจำนวนไบต์
anton_rh

17

เพียงทางเลือก:

ls -lAR | grep -v '^d' | awk '{total += $5} END {print "Total:", total}'

grep -v '^d' จะไม่รวมไดเรกทอรี


4
สมบูรณ์แบบนอกจากนี้ยังเพิ่ม -a param เพื่อรับ "ไฟล์ที่ซ่อน" (อะไรก็ได้ที่เริ่มต้นด้วยจุด)
Nicholi

แยกเป็นประเภทไฟล์เฉพาะ (ในกรณีนี้คือ PNG) และแสดงเป็น MB เพื่อให้อ่านง่ายขึ้น: ls -lR | grep '.png$' | awk '{total += $5} END {print "Total:", total/1024/1024, "MB"}'
MusikPolice

มันเป็นคำตอบที่ถูกต้อง ซึ่งแตกต่างจากduโซลูชันนี้จะนับขนาดรวมของข้อมูลทั้งหมดในไฟล์ราวกับว่าเปิดทีละไฟล์และนับจำนวนไบต์ แต่ใช่การเพิ่ม-Aพารามิเตอร์จะต้องนับไฟล์ที่ซ่อนอยู่ด้วย
anton_rh

13

รูปแบบ "% s" ของ stat ให้จำนวนไบต์ที่แท้จริงในไฟล์

 find . -type f |
 xargs stat --format=%s |
 awk '{s+=$1} END {print s}'

รู้สึกอิสระที่จะทดแทนคุณวิธีการที่ชื่นชอบสำหรับข้อสรุปตัวเลข


4
ควรใช้ "find. -type f -print0 | xargs -0 ... " เพื่อหลีกเลี่ยงปัญหาเกี่ยวกับชื่อไฟล์บางชื่อ (มีช่องว่างเป็นต้น)
hlovdal

1
ใช่จุดที่ดี ถ้ามันไม่ได้อยู่ใน bsd 4.2 ฉันจำไม่ได้ว่าจะใช้มัน :-(
Nelson

3
find -print0และxargs -0จำเป็นสำหรับชื่อไฟล์ที่มีช่องว่าง OS X stat -f %zต้องการ
Kornel

1
(โปรดทราบว่า stat ใช้งานได้กับไฟล์ที่กระจัดกระจายโดยรายงานขนาดไฟล์ที่มีขนาดใหญ่ไม่ใช่บล็อกที่เล็กกว่าที่ใช้บนดิสก์เช่นduรายงาน)
เนลสัน

1
ไม่เหมือนกับคำตอบอื่น ๆ อีกมากมายที่นี่ซึ่งใช้duยูทิลิตี้ผิดพลาดคำตอบนี้ถูกต้อง มันจะคล้ายกันมากที่จะตอบที่นี่: unix.stackexchange.com/a/471061/152606 แต่ฉันจะใช้! -type dแทน-type fการนับ symlink ด้วย (ขนาดของ symlink เอง (โดยปกติจะมีไม่กี่ไบต์) ไม่ใช่ขนาดของไฟล์ที่ชี้ไป)
anton_rh

3

หากคุณใช้ "du" ของ busybox ในระบบ emebedded คุณจะไม่สามารถรับไบต์ที่แน่นอนด้วย du ได้เฉพาะ Kbytes เท่านั้นที่คุณจะได้รับ

BusyBox v1.4.1 (2007-11-30 20:37:49 EST) multi-call binary

Usage: du [-aHLdclsxhmk] [FILE]...

Summarize disk space used for each FILE and/or directory.
Disk space is printed in units of 1024 bytes.

Options:
        -a      Show sizes of files in addition to directories
        -H      Follow symbolic links that are FILE command line args
        -L      Follow all symbolic links encountered
        -d N    Limit output to directories (and files with -a) of depth < N
        -c      Output a grand total
        -l      Count sizes many times if hard linked
        -s      Display only a total for each argument
        -x      Skip directories on different filesystems
        -h      Print sizes in human readable format (e.g., 1K 243M 2G )
        -m      Print sizes in megabytes
        -k      Print sizes in kilobytes(default)

3

เมื่อสร้างโฟลเดอร์ระบบไฟล์ Linux จำนวนมากจะจัดสรร 4096 ไบต์เพื่อจัดเก็บข้อมูลเมตาบางอย่างเกี่ยวกับไดเร็กทอรี พื้นที่นี้จะเพิ่มขึ้นเป็นทวีคูณ 4096 ไบต์เมื่อไดเร็กทอรีเติบโตขึ้น

คำสั่งdu (มีหรือไม่มีตัวเลือก -b) จะนับช่องว่างนี้ดังที่คุณเห็นการพิมพ์:

mkdir test && du -b test

คุณจะได้ผลลัพธ์ 4096 ไบต์สำหรับ dir ว่าง ดังนั้นหากคุณใส่ไฟล์ 2 ไฟล์ที่มี 10,000 ไบต์ไว้ใน dir จำนวนทั้งหมดที่กำหนดโดยdu -sbจะเท่ากับ 24096 ไบต์

หากคุณอ่านคำถามอย่างละเอียดนี่ไม่ใช่สิ่งที่ถาม ผู้ถามถามว่า

ผลรวมของข้อมูลทั้งหมดในไฟล์และไดเร็กทอรีย่อยที่ฉันจะได้รับถ้าฉันเปิดแต่ละไฟล์และนับไบต์

ในตัวอย่างด้านบนควรเป็น 20000 ไบต์ไม่ใช่ 24096

ดังนั้นคำตอบที่ถูกต้อง IMHO อาจเป็นการผสมผสานระหว่างคำตอบของเนลสันและคำแนะนำhlovdalเพื่อจัดการชื่อไฟล์ที่มีช่องว่าง:

find . -type f -print0 | xargs -0 stat --format=%s | awk '{s+=$1} END {print s}'

2

มีอย่างน้อยสามวิธีในการรับ "ผลรวมของข้อมูลทั้งหมดในไฟล์และไดเร็กทอรีย่อย" เป็นไบต์ที่ทำงานได้ทั้งใน Linux / Unix และ Git Bash สำหรับ Windows โดยเรียงลำดับจากเร็วที่สุดไปยังช้าที่สุดโดยเฉลี่ย สำหรับการอ้างอิงของคุณไฟล์เหล่านี้ถูกเรียกใช้ที่รูทของระบบไฟล์ที่ค่อนข้างลึก ( docrootในการติดตั้ง Magento 2 Enterprise ประกอบด้วยไฟล์ 71,158 ไฟล์ใน 30,027 ไดเร็กทอรี)

1.

$ time find -type f -printf '%s\n' | awk '{ total += $1 }; END { print total" bytes" }'
748660546 bytes

real    0m0.221s
user    0m0.068s
sys     0m0.160s

2.

$ time echo `find -type f -print0 | xargs -0 stat --format=%s | awk '{total+=$1} END {print total}'` bytes
748660546 bytes

real    0m0.256s
user    0m0.164s
sys     0m0.196s

3.

$ time echo `find -type f -exec du -bc {} + | grep -P "\ttotal$" | cut -f1 | awk '{ total += $1 }; END { print total }'` bytes
748660546 bytes

real    0m0.553s
user    0m0.308s
sys     0m0.416s


ทั้งสองนี้ใช้งานได้เช่นกัน แต่ต้องอาศัยคำสั่งที่ไม่มีใน Git Bash สำหรับ Windows:

1.

$ time echo `find -type f -printf "%s + " | dc -e0 -f- -ep` bytes
748660546 bytes

real    0m0.233s
user    0m0.116s
sys     0m0.176s

2.

$ time echo `find -type f -printf '%s\n' | paste -sd+ | bc` bytes
748660546 bytes

real    0m0.242s
user    0m0.104s
sys     0m0.152s


หากคุณต้องการเพียงผลรวมสำหรับไดเร็กทอรีปัจจุบันให้เพิ่มลง-maxdepth 1ในfind.


โปรดทราบว่าโซลูชันที่แนะนำบางส่วนไม่ให้ผลลัพธ์ที่ถูกต้องดังนั้นฉันจึงใช้วิธีแก้ปัญหาข้างต้นแทน

$ du -sbh
832M    .

$ ls -lR | grep -v '^d' | awk '{total += $5} END {print "Total:", total}'
Total: 583772525

$ find . -type f | xargs stat --format=%s | awk '{s+=$1} END {print s}'
xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option
4390471

$ ls -l| grep -v '^d'| awk '{total = total + $5} END {print "Total" , total}'
Total 968133

1
เกี่ยวกับ Git Bash สำหรับ Windows - ในกรณีของ Cygwin, dcเป็นส่วนหนึ่งของbcแพคเกจเพื่อที่จะได้รับdcbcมันจะต้องติดตั้ง
ruvim

1

สำหรับ Win32 DOS คุณสามารถ:

c:> dir / sc: \ directory \ you \ want

และบรรทัดสุดท้ายจะบอกคุณว่าไฟล์ใช้เวลากี่ไบต์

ฉันรู้ว่าสิ่งนี้อ่านไฟล์และไดเรกทอรีทั้งหมด แต่ทำงานได้เร็วขึ้นในบางสถานการณ์


1

duมีประโยชน์ แต่findมีประโยชน์ในกรณีที่คุณต้องการคำนวณขนาดของไฟล์บางไฟล์เท่านั้น (ตัวอย่างเช่นใช้ตัวกรองตามนามสกุล) โปรดทราบว่าfindตัวเองสามารถพิมพ์ขนาดของแต่ละไฟล์เป็นไบต์ ในการคำนวณขนาดทั้งหมดเราสามารถเชื่อมต่อdcคำสั่งในลักษณะต่อไปนี้:

find . -type f -printf "%s + " | dc -e0 -f- -ep

ที่นี่findสร้างลำดับของคำสั่งสำหรับเช่นdc 123 + 456 + 11 +แม้ว่าโปรแกรมที่เสร็จสมบูรณ์ควรเป็นอย่างไร0 123 + 456 + 11 + p(จำสัญกรณ์ postfix)

ดังนั้นเพื่อให้ได้โปรแกรมที่เสร็จสมบูรณ์เราต้องวาง0บนสแต็กก่อนที่จะดำเนินการตามลำดับจาก stdin และพิมพ์หมายเลขบนสุดหลังจากเรียกใช้งาน ( pคำสั่งที่อยู่ท้าย) เราบรรลุได้ด้วยdcตัวเลือก:

  1. -e0เป็นเพียงทางลัด-e '0'ที่วาง0บนสแต็ก
  2. -f-มีไว้สำหรับอ่านและดำเนินการคำสั่งจาก stdin (ที่สร้างโดยfindที่นี่)
  3. -epใช้สำหรับพิมพ์ผลลัพธ์ ( -e 'p')

ในการพิมพ์ขนาดใน MiB อย่างที่284.06 MiBเราสามารถใช้-e '2 k 1024 / 1024 / n [ MiB] p'ในจุดที่ 3 แทน (ช่องว่างส่วนใหญ่เป็นทางเลือก)


1

สิ่งนี้อาจช่วยได้:

ls -l| grep -v '^d'| awk '{total = total + $5} END {print "Total" , total}'

คำสั่งดังกล่าวจะรวมไฟล์ทั้งหมดออกจากขนาดไดเร็กทอรี


1
โปรดทราบว่าคำตอบนี้คล้ายกับคำตอบของ Barun มาก แต่วิธีนี้ไม่รวมไฟล์ในไดเรกทอรีย่อย
ruvim

1
@ruvim มันไม่รวมไฟล์ที่ซ่อนอยู่ด้วย ผลรวมซ่อนไฟล์ที่ตัวเลือกที่จะต้องเพิ่ม-A ls
anton_rh

0

ใช้:

$ du -ckx <DIR> | grep total | awk '{print $1}'

โดย <DIR> คือไดเร็กทอรีที่คุณต้องการตรวจสอบ

'-c' ให้ข้อมูลทั้งหมดจำนวนมากซึ่งถูกแยกโดยใช้ส่วน 'grep total' ของคำสั่งและจำนวนใน Kbytes จะถูกดึงออกมาด้วยคำสั่ง awk

ข้อแม้เดียวที่นี่คือถ้าคุณมีไดเรกทอรีย่อยที่มีข้อความ "ทั้งหมด" มันก็จะถูกคายออกไปเช่นกัน

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