จะค้นหาไฟล์ที่ใหญ่ที่สุดในไดเร็กทอรีและไดเร็กทอรีย่อยได้อย่างไร


102

เราเพิ่งเริ่มคลาส UNIX และกำลังเรียนรู้คำสั่ง Bash ที่หลากหลาย งานของเราเกี่ยวข้องกับการดำเนินการคำสั่งต่างๆในไดเร็กทอรีที่มีโฟลเดอร์จำนวนมากอยู่ข้างใต้เช่นกัน

ฉันรู้วิธีแสดงรายการและนับไฟล์ปกติทั้งหมดจากโฟลเดอร์รูทโดยใช้:

find . -type l | wc -l

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

และยกโทษให้ฉันถ้า 'ศัพท์แสง' ของฉันไม่ถูกต้องฉันก็ยังชินอยู่ดี!


2
หากคุณรู้จักคำสั่ง แต่ไม่แน่ใจว่าจะใช้อย่างไรให้ลองพิมพ์manตามด้วยคำสั่งที่คุณสนใจ Up จะปรากฏรายการคู่มือที่ดีสำหรับคำสั่งนั้น (กดqเพื่อกลับไปที่บรรทัดคำสั่ง)
Dunes

คำตอบ:


126

อ้างจากลิงค์นี้ -

หากคุณต้องการค้นหาและพิมพ์ชื่อไฟล์ที่ใหญ่ที่สุด 10 อันดับแรก (ไม่ใช่ไดเร็กทอรี) ในไดเร็กทอรีเฉพาะและไดเร็กทอรีย่อย

$ find . -printf '%s %p\n'|sort -nr|head

ในการ จำกัด การค้นหาไว้ที่ไดเร็กทอรีปัจจุบันให้ใช้ "-maxdepth 1" กับ find

$ find . -maxdepth 1 -printf '%s %p\n'|sort -nr|head

และในการพิมพ์ "ไฟล์และไดเรกทอรี" ที่ใหญ่ที่สุด 10 อันดับแรก:

$ du -a . | sort -nr | head

** ใช้ "head -n X" แทน "head" เพียงตัวเดียวด้านบนเพื่อพิมพ์ไฟล์ที่ใหญ่ที่สุด X อันดับต้น ๆ (ในตัวอย่างข้างต้นทั้งหมด)


1
เหตุใด "du -a. | sort -nr | head" จึงส่งคืนจำนวน KB ที่มากกว่าขนาดไฟล์จริงเป็นสองเท่า
xxjjnn

6
อ่าคุณต้องเพิ่มตัวเลือก 'k' หรือมันจะแสดงผลคูณ 512 ไบต์แทนที่จะเป็น 1024 du
-ak

2
สำหรับคนแรกคุณจะได้ขนาดในรูปแบบที่มนุษย์อ่านได้อย่างไร?
Bluz

@ บลูซฉันจะลองแทนที่'%s %p\n'ด้วย'%p\n'และเพิ่ม|xargs ls -lhในตอนท้าย
Duncan X Simpson

6
วิธีแรกไม่ได้ทำงานบน OS X du -am . | sort -nr | grep '\..*\.' | headสำหรับฉันดังนั้นฉันสิ้นสุดที่ใช้สับรวดเร็วในการกรองไดเรกทอรีจากการแก้ปัญหาที่สาม: mคือการแสดงผลขนาดไฟล์เมกะไบต์และใช้grepกับสายการแสดงอย่างน้อยสองจุดเป็นครั้งแรกในในเส้นทางที่สองคือในส่วนขยายของแฟ้มเช่น./ .mov
psmith

63

หากต้องการค้นหาไฟล์ 25 อันดับแรกในไดเร็กทอรีปัจจุบันและไดเร็กทอรีย่อย:

find . -type f -exec ls -al {} \; | sort -nr -k5 | head -n 25

สิ่งนี้จะส่งออกไฟล์ 25 อันดับแรกโดยการจัดเรียงตามขนาดของไฟล์ผ่านคำสั่ง piped "sort -nr -k5"

เหมือนกัน แต่มีขนาดไฟล์ที่มนุษย์อ่านได้:

find . -type f -exec ls -alh {} \; | sort -hr -k5 | head -n 25


10
find . -type f | xargs ls -lS | head -n 1

เอาต์พุต

-rw-r--r--  1 nneonneo  staff  9274991 Apr 11 02:29 ./devel/misc/test.out

หากคุณต้องการเพียงแค่ชื่อไฟล์:

find . -type f | xargs ls -1S | head -n 1

หลีกเลี่ยงการใช้นี้และช่วยให้คุณใช้ธงสิ่งที่คุณต้องการในawkls

ข้อแม้ เนื่องจากxargsพยายามหลีกเลี่ยงการสร้างบรรทัดคำสั่งที่ยาวเกินไปจึงอาจล้มเหลวหากคุณรันบนไดเร็กทอรีที่มีไฟล์จำนวนมากเนื่องจากlsลงเอยด้วยการดำเนินการมากกว่าหนึ่งครั้ง ไม่ใช่ปัญหาที่ผ่านไม่ได้ (คุณสามารถรวบรวมhead -n 1ผลลัพธ์จากlsการเรียกแต่ละครั้งและเรียกใช้ls -Sอีกครั้งวนซ้ำจนกว่าคุณจะมีไฟล์เดียว) แต่ก็ใช้วิธีนี้ได้บ้าง


1
ฉันขอโทษxargsฉันละเลยคุณ +1
สตีฟ

2
ในการจัดการชื่อไฟล์ที่มีช่องว่างให้ใช้find . -type f -print0 | xargs -0 ls -lS | head -n 1
rymo

สิ่งนี้จะพบไฟล์ที่ใหญ่ที่สุดในชุดแรกเท่านั้นที่xargsดำเนินการ ในการแก้ไขให้เพิ่มการเรียงลำดับ: find . -type f -print0 | xargs -0 ls -lS | sort -rk 5 | head -n 10. ทำงานบน OSX ให้ฉัน
psmith

10

ไม่มีคำสั่งง่ายๆในการค้นหาไฟล์ / ไดเร็กทอรีที่ใหญ่ที่สุดบนระบบไฟล์ Linux / UNIX / BSD อย่างไรก็ตามการรวมกันของคำสั่งสามคำสั่งต่อไปนี้ (โดยใช้ไปป์) คุณสามารถค้นหารายการไฟล์ที่ใหญ่ที่สุด:

# du -a /var | sort -n -r | head -n 10

หากคุณต้องการผลลัพธ์ที่มนุษย์อ่านได้มากขึ้นลอง:

$ cd /path/to/some/var
$ du -hsx * | sort -rh | head -10

ที่ไหน

  • Varคือไดเร็กทอรีที่คุณต้องการค้นหา
  • du command -h option:แสดงขนาดในรูปแบบที่มนุษย์อ่านได้ (เช่น 1K, 234M, 2G)
  • du command -s option:แสดงเฉพาะผลรวมสำหรับแต่ละอาร์กิวเมนต์ (สรุป)
  • อ็อพชันคำสั่ง du -x:ข้ามไดเร็กทอรีบนระบบไฟล์อื่น
  • ตัวเลือกคำสั่ง sort -r:ย้อนกลับผลลัพธ์ของการเปรียบเทียบ
  • เรียงลำดับคำสั่ง -h ตัวเลือก:เปรียบเทียบตัวเลขที่มนุษย์อ่านได้ นี่คือตัวเลือกเฉพาะการจัดเรียง GNU เท่านั้น
  • คำสั่ง head -10 หรือ -n 10 ตัวเลือก:แสดง 10 บรรทัดแรก

ฉันชอบคำสั่งที่ 2 ดีกว่า แต่ใน osx ไม่มีตัวเลือก -h สำหรับการเรียงลำดับเวอร์ชันที่ติดตั้ง ควรเป็นสำหรับ mac: du -hsx * | เรียง -rn | หัว -10
Yann VR

1
รักคำสั่งที่สอง! สิ่งที่ดีที่สุดที่ฉันได้ลอง - ฉันจะบันทึกไว้ในภายหลัง
CodeMouse92

อธิบายคำสั่งอย่างละเอียดชัดเจน +1
Harish

8

สิ่งนี้จะแสดงรายการไฟล์แบบวนซ้ำหากเป็นไฟล์ปกติจัดเรียงตามฟิลด์ที่ 7 (ซึ่งเป็นขนาดในfindผลลัพธ์ของฉันตรวจสอบของคุณ) และแสดงเพียงไฟล์แรก

find . -type f -ls | sort +7 | head -1

ตัวเลือกแรกfindคือเส้นทางเริ่มต้นสำหรับการค้นหาแบบวนซ้ำ ประเภทของfการค้นหาไฟล์ปกติ โปรดทราบว่าหากคุณพยายามแยกวิเคราะห์เป็นชื่อไฟล์คุณอาจล้มเหลวหากชื่อไฟล์มีช่องว่างบรรทัดใหม่หรืออักขระพิเศษอื่น ๆ ตัวเลือกsortยังแตกต่างกันไปตามระบบปฏิบัติการ ฉันใช้ FreeBSD

วิธีแก้ปัญหาที่ "ดีกว่า" แต่ซับซ้อนและหนักกว่าคือการfindสำรวจไดเร็กทอรี แต่อาจใช้statเพื่อรับรายละเอียดเกี่ยวกับไฟล์จากนั้นอาจใช้awkเพื่อค้นหาขนาดที่ใหญ่ที่สุด โปรดทราบว่าผลลัพธ์ของstatยังขึ้นอยู่กับระบบปฏิบัติการของคุณ


1
คืออะไร+7หาเรื่องหมายความว่าจะต้องทำอะไร ในการเรียงลำดับเครื่องของฉันบ่นว่าไม่พบไฟล์ที่เรียกว่า+7.
ดูนส์

@Dunes - อย่างที่บอกตรวจสอบหน้าคนสำหรับsortระบบของคุณ ฉันใช้ OS X 10.4 ในขณะที่บุคลากรการใช้งานจากการเรียงลำดับของ FreeBSD : sort [-cmus] [-t separator] [-o output-file] [-T tempdir] [-bdfiMnr] [+POS1 [-POS2]] [-k POS1[,POS2]] [file...]... +POS [-POS2]หมายเหตุ สิ่งนี้ใช้ได้กับ FreeBSD เวอร์ชันปัจจุบันด้วย
ghoti

2
ดูเหมือนว่าคุณมีโปรแกรมจัดเรียงอื่นสำหรับฉัน นี่คือหน้าคนสำหรับโปรแกรมเรียงลำดับของฉัน - linux.die.net/man/1/sortเพื่อให้สิ่งนี้ทำงานบนเครื่องของฉันคุณจะต้องใช้-kอาร์กิวเมนต์อย่างชัดเจน sort -k 7. แก้ไข: โดย OSX 10.5 หน้า man สำหรับการจัดเรียงดูเหมือนจะเปลี่ยนเป็นเวอร์ชันที่ฉันมี
Dunes

1
@Dunes - เป็น GNU ทั้งหมด แต่เป็นเวอร์ชันที่แตกต่างกัน [+POS1] [-POS2]สัญกรณ์เป็นเพียงหนึ่งที่มีอายุมากกว่า เท่าที่ฉันสามารถบอกได้ว่าสัญกรณ์นี้ยังคงได้รับการสนับสนุนโดยการเรียงลำดับ GNU สมัยใหม่แม้ว่าตอนนี้ฉันดูแล้วดูเหมือนว่าจะถูกทิ้งจากหน้าคนจัดเรียงหลังจากประมาณเวอร์ชัน 5.1 คุณสามารถดูได้ในหน้าคนสำหรับการจัดเรียงสำหรับ FreeBSD 4.11 ฉันเดาว่าฉันไม่ได้อ่าน man page ของ sort ตั้งแต่ก่อน FreeBSD 5.0 ​​ออก!
ghoti

นอกจากนี้โปรดทราบว่า+POS1นับพารามิเตอร์การเรียงลำดับจากศูนย์ในขณะที่-k POS1นับจากหนึ่ง
ghoti

6

ซึ่งจะพบไฟล์หรือโฟลเดอร์ที่ใหญ่ที่สุดในไดเร็กทอรีการทำงานปัจจุบันของคุณ:

ls -S /path/to/folder | head -1

หากต้องการค้นหาไฟล์ที่ใหญ่ที่สุดในไดเรกทอรีย่อยทั้งหมด:

find /path/to/folder -type f -exec ls -s {} \; | sort -nr | awk 'NR==1 { $1=""; sub(/^ /, ""); print }'

ฉันคิดว่าพฤติกรรมเริ่มต้นของ ls คือการแสดงรายการไฟล์ในคอลัมน์ (เช่นหลายรายการต่อบรรทัด) ดังนั้นอย่างแรกจึงไม่พบเพียงไฟล์ที่ใหญ่ที่สุด เกี่ยวกับคำสั่งที่สองของคุณจะพบเฉพาะไฟล์ที่ใหญ่ที่สุดในไดเร็กทอรีที่กำหนดไม่ใช่ไดเร็กทอรีย่อย
Dunes

@Dunes: คุณถูกต้องคำสั่งแรกสามารถค้นหาไดเร็กทอรี แต่ไม่ใช่เนื่องจากพฤติกรรมเริ่มต้นของls. ในการทดสอบของฉัน-Sแฟล็กจะแสดงรายการไฟล์หนึ่งไฟล์ต่อบรรทัด ฉันได้แก้ไขคำสั่งที่สองแล้ว หวังว่าตอนนี้จะพิสูจน์ได้เต็มรูปแบบ ขอบคุณ.
Steve

4

บน Solaris ฉันใช้:

find . -type f -ls|sort -nr -k7|awk 'NR==1{print $7,$11}' #formatted

หรือ

find . -type f -ls | sort -nrk7 | head -1 #unformatted

เนื่องจากสิ่งอื่นที่โพสต์ที่นี่ไม่ได้ผล ซึ่งจะพบไฟล์ที่ใหญ่ที่สุดใน$PWDและไดเรกทอรีย่อย


2

ลองใช้ซับเดียวต่อไปนี้ (แสดงไฟล์ที่ใหญ่ที่สุด 20 อันดับแรก):

ls -1Rs | sed -e "s/^ *//" | grep "^[0-9]" | sort -nr | head -n20

หรือ (ขนาดที่มนุษย์อ่านได้):

ls -1Rhs | sed -e "s/^ *//" | grep "^[0-9]" | sort -hr | head -n20

ทำงานได้ดีภายใต้ Linux / BSD / OSX เมื่อเปรียบเทียบกับคำตอบอื่น ๆ เนื่องจาก-printfตัวเลือกของ find ไม่มีอยู่ใน OSX / BSD และstatมีพารามิเตอร์ที่แตกต่างกันขึ้นอยู่กับ OS แต่คำสั่งที่สองในการทำงานใน OSX / BSD ถูกต้อง (ตามsortไม่ได้-h) ติดตั้งsortจากcoreutilsหรือลบ-hจากlsและใช้sort -nrแทน

ดังนั้นนามแฝงเหล่านี้จึงมีประโยชน์ในไฟล์rcของคุณ:

alias big='du -ah . | sort -rh | head -20'
alias big-files='ls -1Rhs | sed -e "s/^ *//" | grep "^[0-9]" | sort -hr | head -n20'

สิ่งนี้จะแสดงเฉพาะชื่อไฟล์ที่ไม่มีเส้นทางดังนั้นจึงไม่ได้ช่วยในการค้นหาไฟล์ที่ใหญ่ที่สุด
psmith

สำหรับฉันแล้วฉันมีไฟล์ที่ใหญ่ที่สุด แต่ในตอนท้ายสิ่งนี้ไม่ได้ให้ไฟล์ที่ถูกต้องแก่ฉัน
Borislav Markov

2

ลองใช้คำสั่งต่อไปนี้:

find /your/path -printf "%k %p\n" | sort -g -k 1,1 | awk '{if($1 > 500000) print $1/1024 "MB" " " $2 }' |tail -n 1 

ซึ่งจะพิมพ์ชื่อไฟล์และขนาดที่ใหญ่ที่สุดและมากกว่า 500M คุณสามารถย้ายif($1 > 500000)และจะพิมพ์ไฟล์ที่ใหญ่ที่สุดในไดเร็กทอรี



0

สคริปต์นี้ช่วยลดความยุ่งยากในการค้นหาไฟล์ที่ใหญ่ที่สุดสำหรับการดำเนินการเพิ่มเติม ฉันเก็บไว้ในไดเร็กทอรี ~ / bin ของฉันและใส่ ~ / bin ใน $ PATH ของฉัน

#!/usr/bin/env bash
# scriptname: above
# author: Jonathan D. Lettvin, 201401220235

# This finds files of size >= $1 (format ${count}[K|M|G|T], default 10G)
# using a reliable version-independent bash hash to relax find's -size syntax.
# Specifying size using 'T' for Terabytes is supported.
# Output size has units (K|M|G|T) in the left hand output column.

# Example:
#   ubuntu12.04$ above 1T
#   128T /proc/core

# http://stackoverflow.com/questions/1494178/how-to-define-hash-tables-in-bash
# Inspiration for hasch: thanks Adam Katz, Oct 18 2012 00:39
function hasch() { local hasch=`echo "$1" | cksum`; echo "${hasch//[!0-9]}"; }
function usage() { echo "Usage: $0 [{count}{k|K|m|M|g|G|t|T}"; exit 1; }
function arg1() {
    # Translate single arg (if present) into format usable by find.
    count=10; units=G;  # Default find -size argument to 10G.
    size=${count}${units}
    if [ -n "$1" ]; then
        for P in TT tT GG gG MM mM Kk kk; do xlat[`hasch ${P:0:1}`]="${P:1:1}"; done
        units=${xlat[`hasch ${1:(-1)}`]}; count=${1:0:(-1)}
        test -n "$units" || usage
        test -x $(echo "$count" | sed s/[0-9]//g) || usage
        if [ "$units" == "T" ]; then units="G"; let count=$count*1024; fi
        size=${count}${units}
    fi
}
function main() {
    sudo \
        find / -type f -size +$size -exec ls -lh {} \; 2>/dev/null | \
        awk '{ N=$5; fn=$9; for(i=10;i<=NF;i++){fn=fn" "$i};print N " " fn }'
}

arg1 $1
main $size

0

นั่นเป็นวิธีที่ง่ายกว่าในการทำ:

ls -l | tr -s " " " " | cut -d " " -f 5,9 | sort -n -r | head -n 1***

และคุณจะได้รับสิ่งนี้: 8445 examples.desktop


สิ่งที่1***ควรทำในตอนท้าย? ฉันได้รับข้อผิดพลาด "ไม่พบรายการที่ตรงกัน" สำหรับอาร์กิวเมนต์นั้น
user4815162342

0

โซลูชัน Linux:ตัวอย่างเช่นคุณต้องการดูรายการไฟล์ / โฟลเดอร์ทั้งหมดของไดเร็กทอรี home (/) ตามขนาดไฟล์ / โฟลเดอร์ ( เรียงลำดับจากมากไปหาน้อย )

sudo du -xm / | เรียง -rn | มากกว่า


0

เพื่อแสดงรายการไฟล์ขนาดใหญ่ในโฟลเดอร์

ls -sh /pathFolder | sort -rh | head -n 1

ผลลัพธ์ของls -shคือขนาดsและhมุมมองที่มนุษย์เข้าใจได้ของหมายเลขขนาดไฟล์

คุณสามารถใช้ls -shS /pathFolder | head -n 1. ยิ่งใหญ่ขึ้นSจากการlsเรียงลำดับรายการจากไฟล์ขนาดใหญ่ไปยังไฟล์ที่มีขนาดเล็กกว่า แต่ผลลัพธ์แรกคือผลรวมของไฟล์ทั้งหมดในโฟลเดอร์นั้น ดังนั้นหากคุณต้องการเพียงแค่แสดงรายการไฟล์ที่ใหญ่กว่าไฟล์เดียวคุณต้องhead -n 2ตรวจสอบที่ "ผลลัพธ์บรรทัดที่สอง" หรือใช้ตัวอย่างแรกกับls sort head.


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