การค้นหาไฟล์ที่ใหญ่ที่สุดแบบเรียกซ้ำ


41

ฉันพยายามค้นหาไฟล์ที่ใหญ่ที่สุดในไดเรกทอรีแบบเรียกซ้ำ หากมีไดเรกทอรีย่อยในไดเรกทอรีนั้นฟังก์ชันนั้นจะต้องเข้าไปข้างในไดเรกทอรีนั้นและตรวจสอบว่ามีไฟล์ที่ใหญ่ที่สุดหรือไม่ เมื่อพบไฟล์ที่ใหญ่ที่สุดเอาต์พุตจะถูกแสดงด้วยชื่อพา ธ สัมพัทธ์และชื่อและขนาดของไฟล์ที่ใหญ่ที่สุด

EX:

dude@shell2 (~...assignment/solutions) % bash maxfile.sh ~/test
class/asn
dude.h.gch: 9481628

นี่คือสิ่งที่ฉันมี:

#!/bin/sh
clear

recursiveS() {
    for d in *; do
        if [ -d $d ]; then
            (cd $d; echo $(pwd)/$line; du -a; recursiveS;)
        fi
    done
}
recursiveS

ฉันติดขัดอยู่พักหนึ่งแล้ว ฉันไม่สามารถใช้สิ่งนี้ได้โดยการวางท่อจำนวนเครื่องมือ Unix ที่มีอยู่ ความคิดใด ๆ จะดี!



ไปในตำบลเท่านั้น: for d in */ .[^.]*/; ทำ ... `
Olivier Dulac

คำตอบ:


54

ใช้find(ที่นี่สมมติว่า GNU find) เพื่อส่งออกชื่อไฟล์ด้วยขนาดไฟล์ ประเภท พิมพ์ที่ใหญ่ที่สุด

find . -type f -printf "%s\t%p\n" | sort -n | tail -1

ซึ่งถือว่าเส้นทางไฟล์ไม่มีอักขระขึ้นบรรทัดใหม่


การใช้การวนซ้ำbashกับการใช้ GNU ของstat:

shopt -s globstar
max_s=0
for f in **; do
  if [[ -f "$f" && ! -L "$f" ]]; then
    size=$( stat -c %s -- "$f" )
    if (( size > max_s )); then
      max_s=$size
      max_f=$f
    fi
  fi
done
echo "$max_s $max_f"

สิ่งนี้จะช้ากว่าโซลูชันการค้นหาอย่างมาก และยังสันนิษฐานว่าชื่อไฟล์ไม่ได้ลงท้ายด้วยอักขระขึ้นบรรทัดใหม่และจะข้ามไฟล์ที่ซ่อนอยู่และไม่ลงไปในไดเรกทอรีที่ซ่อนอยู่

หากมีไฟล์ที่เรียกว่า-ในไดเรกทอรีปัจจุบันขนาดของไฟล์ที่เปิดใน stdin จะถูกพิจารณา

ระวังเวอร์ชันbashก่อนหน้า 4.3 ตามลิงค์สัญลักษณ์เมื่อสืบทอดแผนผังไดเรกทอรี


ขอบคุณมันใช้งานได้! ฉันขอขอบคุณความช่วยเหลือ ฉันพยายามใช้โปรแกรมในเชลล์ ฉันไม่ได้รู้อะไรมากมายเลยตอนนี้ดังนั้นฉันขอขอบคุณที่คุณบอกฉันว่าเกิดอะไรขึ้นกับบรรทัดของโค้ดนั้น
2419571

คำถามด่วน: อยากรู้อยากเห็นมีวิธีการทำโดยไม่ต้องคำสั่ง piping? ฉันอยากรู้อยากเห็นเพราะทุกตัวอย่างที่ฉันเห็นได้ใช้ท่อบางชนิด
2419571

2
ฉันแน่ใจว่ามีวิธีอื่นที่จะทำ ปรัชญา UNIX คือเครื่องมือควรมีจุดประสงค์เดียวและเชื่อมโยงเข้าด้วยกันดังนั้นผลลัพธ์ของคำสั่งเดียวจะถูกป้อนเข้าสู่อินพุตของถัดไป
เกล็นแจ็คแมน

นั่นทำให้รู้สึก ขอบคุณอีกครั้งสำหรับความช่วยเหลือของคุณ
2419571

2
@ user2419571:; tail -n 1 <(sort -n <(find . -type f -printf "%s\t%p\n")))
Cyrus


5

สิ่งนี้ใช้ได้กับ BSD / macOS:

find . -type f -ls | sort -k7 -r

คุณสามารถต่อท้าย| head -n 3เพื่อแสดงจำนวนรายการที่น่าสนใจ (3 ในกรณีนี้)


1
คำตอบนี้สามารถปรับปรุงได้โดยอธิบายว่ามันทำงานอย่างไร นอกจากนี้ยังมีลักษณะคล้ายกับคำตอบที่ยอมรับ (ซึ่งไม่ได้อธิบายอย่างสมบูรณ์ถึงวิธีการใช้งาน)
dhag

man findและman sortใช้ brainz :-)
CeDeROM

ไม่ทำงานบน MacOS เนื่องจากไม่สามารถคืนขนาดได้อย่างถูกต้องและส่งคืนคอลัมน์จำนวนมาก
โซริน

3

ด้วยzshสำหรับไฟล์ปกติที่ใหญ่ที่สุด:

ls -ld -- **/*(.DOL[1])

(แน่นอนคุณสามารถแทนที่ls -ld --ด้วยคำสั่งใด ๆ หากใช้ GNU lsหรือเข้ากันได้ดู-hตัวเลือกสำหรับขนาดที่มนุษย์สามารถอ่านได้ )

  • .: ไฟล์ปกติเท่านั้น(ไม่ใช่ไดเรกทอรี, symlink, อุปกรณ์, fifos ... )
  • D: รวมคนที่ซ่อนอยู่และสืบเชื้อสายมาลงใน dir
  • OL: เรียงกลับตามขนาด ( Length)
  • [1]: เฉพาะนัดแรก

หากมีความสัมพันธ์คุณจะได้รับหนึ่งในนั้นโดยการสุ่ม หากคุณต้องการอันดับแรกตามลำดับตัวอักษรให้เพิ่มส่วนพิเศษon( order by name) เพื่อเรียงลำดับการเรียงตามตัวอักษร

โปรดทราบว่ามันพิจารณาขนาดไฟล์ไม่ใช่การใช้ดิสก์


... ฉันเริ่มที่จะเชื่อว่าคุณอยู่ในบัญชีเงินเดือนของ zsh;) (ซึ่งมันอาจเป็นไปได้?) zsh เป็นที่น่าเสียดายที่ไม่สามารถใช้ได้ในระบบทั้งหมด ...
โอลิเวีย Dulac

เป็นไปได้ที่จะรับสิบไฟล์แรก? (โดยไม่ต้องทำอะไรโง่ ๆ เหมือนวงวน)
Wowfunhappy

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