ขนาดของไฟล์ทั้งหมดของนามสกุลที่แน่นอนในแผนผังไดเรกทอรี


17

ฉันต้องการทราบขนาดของไฟล์ที่มีนามสกุล. o (ไฟล์วัตถุ) ในโฟลเดอร์ Home ของฉัน

ฉันสามารถค้นหาไฟล์วัตถุทั้งหมดที่ใช้

find . -name '*.o'

ฉันจะคำนวณขนาดรวมของไฟล์เหล่านั้นได้อย่างไร

คำตอบ:


24

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

find . -name "*.o" | xargs du -sch
  • คุณควรเสมอพูดรูปแบบที่คุณให้กับfind(ที่ผมได้ขึ้นไป: "*.o") ถ้าคุณทำไม่ได้เชลล์จะขยาย*.oไปยังชื่อของไฟล์ที่ตรงกันในไดเรกทอรีปัจจุบัน มันทำงานได้ในกรณีนี้เท่านั้นเพราะคุณไม่มีไฟล์ที่ตรงกัน

  • -schธงสำหรับduการบันทึกไว้ในman du:

    -c, --total
          produce a grand total
    -h, --human-readable
          print sizes in human readable format (e.g., 1K 234M 2G)
    -s, --summarize
          display only a total for each argument
    

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

find . -name "*.o" -print0 | xargs -0 du -sch

-print0ทำให้findพิมพ์บรรทัดโมฆะแยกและ-0ทำให้xargsใช้เส้นดังกล่าวเป็น input

หรือคุณสามารถfindพิมพ์ขนาดตัวเองแล้วรวมขนาดเหล่านี้:

find . -name "*.o" -printf '%s\n' | awk '{c+=$1}END{print c}'

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


หากคุณกำลังใช้bash(อาจเป็น) มันมีวิธีที่ง่ายกว่า:

shopt -s globstar 
du -sch **/*.o

shopt globstarทำให้คำสั่ง**ตรงกับไฟล์และไดเรกทอรีย่อยทั้งหมดหรือมากกว่า ทำให้มันหลังจาก, **/*.oจะตรงกับไฟล์ทั้งหมด (และไดเรกทอรี) ที่มีชื่อในปลายเพื่อให้เราสามารถผ่านที่ตรงไปยัง.odu

โปรดทราบว่าfindวิธีนี้จะไม่ตรงกับไฟล์ที่ซ่อนอยู่ซึ่งต่างจากวิธีที่ใช้ซึ่งมีชื่อขึ้นต้นด้วย a .) หากต้องการจับคู่เหล่านั้นเช่นกันให้ทำ:

shopt -s dotglob globstar
du -sch **/*.o

มีปัญหาเล็กน้อยกับอันแรก มีสิ่งเช่น MAXARGS ดังนั้นจะมีการวนซ้ำหลายครั้งduและจะสร้างหลายtotalบรรทัด นี่คือตัวอย่าง: paste.ubuntu.com/23092752
Sergiy Kolodyazhnyy

@Serg จริง ฉันเพิ่มตัวเลือกอื่นที่หลีกเลี่ยง
terdon

shopt globstarตัวอย่างแรกของคุณ-sคือ ฉันต้องใช้shopt -s globstarคล้ายกับตัวอย่างที่สองของคุณ
CrazyPyro

@CrazyPyro d'oh! ขออภัยนั่นเป็นคำที่พิมพ์ผิด ขอบคุณที่ชี้นำ shopt OPTIONโดยไม่ต้อง-sหรือ-u(หรือตัวเลือกอื่น ๆ ดูhelp shopt) เพียงพิมพ์ค่าปัจจุบันของ OPTION คุณต้องshopt -s OPTIONเปิดและshopt -u OPTIONปิด
terdon

8

ใช้การ-exec ตั้งค่าสถานะเพื่อเรียกใช้duคำสั่งด้วย ;(หมายถึงแต่ละไฟล์)

find . -name "*.o" -exec du -b {} \; | awk '{total+=$1}END{print total}' 

ตัวอย่างผลลัพธ์:

$ find . -name "*.txt"  -exec du -b {} \; | awk '{total+=$1}END{print total,"bytes" }'                                     
find: ‘./.cache/gvfs-burn’: Permission denied
find: ‘./.cache/unity’: Permission denied
852690242 bytes

findเป็นแบบเรียกซ้ำ - หมายถึงมันจะผ่านไดเรกทอรีย่อยทั้งหมด หากคุณต้องการรับผลรวมของ*.oไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันให้ทำ

du -b -c *.o

0

ด้วย perl:

perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf

ขนาดของไฟล์ PDF ที่ไม่ถูกซ่อนทั้งหมดในไดเรกทอรีปัจจุบัน


1
ตกลง แต่ OP กำลังค้นหา.oไฟล์และอาจอยู่ในไดเรกทอรีย่อย คุณอาจต้องการเพิ่ม}{ก่อนprint $sumเพื่อหลีกเลี่ยงการพิมพ์ผลรวมสำหรับการวนซ้ำทุกครั้ง เราต้องการแค่อันสุดท้าย
terdon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.