ฉันต้องการทราบขนาดของไฟล์ที่มีนามสกุล. o (ไฟล์วัตถุ) ในโฟลเดอร์ Home ของฉัน
ฉันสามารถค้นหาไฟล์วัตถุทั้งหมดที่ใช้
find . -name '*.o'
ฉันจะคำนวณขนาดรวมของไฟล์เหล่านั้นได้อย่างไร
ฉันต้องการทราบขนาดของไฟล์ที่มีนามสกุล. o (ไฟล์วัตถุ) ในโฟลเดอร์ Home ของฉัน
ฉันสามารถค้นหาไฟล์วัตถุทั้งหมดที่ใช้
find . -name '*.o'
ฉันจะคำนวณขนาดรวมของไฟล์เหล่านั้นได้อย่างไร
คำตอบ:
คุณกำลังมองหาท่อ ( |) เป็นวิธีการเชื่อมต่อหลายคำสั่งและส่งผ่านเอาต์พุตของคำสั่งหนึ่งเป็นอินพุตไปยังอีกคำสั่งหนึ่ง ในกรณีนี้คุณต้องการส่งชื่อไฟล์ทั้งหมดที่คุณค้นหาเป็นอินพุต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
shopt globstarตัวอย่างแรกของคุณ-sคือ ฉันต้องใช้shopt -s globstarคล้ายกับตัวอย่างที่สองของคุณ
shopt OPTIONโดยไม่ต้อง-sหรือ-u(หรือตัวเลือกอื่น ๆ ดูhelp shopt) เพียงพิมพ์ค่าปัจจุบันของ OPTION คุณต้องshopt -s OPTIONเปิดและshopt -u OPTIONปิด
ใช้การ-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
ด้วย perl:
perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf
ขนาดของไฟล์ PDF ที่ไม่ถูกซ่อนทั้งหมดในไดเรกทอรีปัจจุบัน
.oไฟล์และอาจอยู่ในไดเรกทอรีย่อย คุณอาจต้องการเพิ่ม}{ก่อนprint $sumเพื่อหลีกเลี่ยงการพิมพ์ผลรวมสำหรับการวนซ้ำทุกครั้ง เราต้องการแค่อันสุดท้าย
duและจะสร้างหลายtotalบรรทัด นี่คือตัวอย่าง: paste.ubuntu.com/23092752