ฉันต้องการทราบขนาดของไฟล์ที่มีนามสกุล. 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
จะตรงกับไฟล์ทั้งหมด (และไดเรกทอรี) ที่มีชื่อในปลายเพื่อให้เราสามารถผ่านที่ตรงไปยัง.o
du
โปรดทราบว่า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