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


9

ฉันต้องการแสดงรายการเนื้อหาทั้งหมดของไดเรกทอรีรวมถึงเนื้อหาของโฟลเดอร์ย่อย แต่เรียงตามขนาดไฟล์ จนถึงตอนนี้ฉันสามารถจัดการให้ได้มากที่สุดเท่าที่มีในรายการและเรียงลำดับในขณะที่ยังคงซ้ำซากls -lhSR( hดีที่มี แต่ไม่จำเป็นสำหรับฉันตราบใดที่ฉันสามารถมีขนาดไฟล์ได้) ฉันอาจจะมองเห็นสิ่งที่ชัดเจนหรือถามสิ่งที่เป็นไปไม่ได้ แต่คำแนะนำใด ๆ ที่นี่จะได้รับการชื่นชมอย่างมาก

คำตอบ:


15

คุณสามารถใช้ค้นหา:

find . -type f -printf "%s %P\n" | sort -n

ทางเลือก: เมื่อต้องการแปลงค่าไบต์เป็นรูปแบบที่มนุษย์สามารถอ่านได้ให้เพิ่มสิ่งนี้:

| numfmt --to=iec-i --field=1

คำอธิบาย:

 find in current directory (.) all files (-type f) 

 -printf: suppress normal output and print the following:
     %s - size in bytes
     %P - path to file
     \n - new line

 | sort -n: sort the result (-n = numeric)

โอ้สมบูรณ์แบบ! ขอบคุณมากนี่เป็นสิ่งที่ฉันต้องการ!
ทอมส์

3
ฉันดีใจที่คำตอบของฉันช่วยคุณ โปรดพิจารณาการคลิกเครื่องหมายถูกที่ด้านซ้ายเพื่อทำเครื่องหมายคำตอบที่ยอมรับ ขอบคุณ
pLumo

1
@RoVo มันจะดีกว่าที่จะถอนรากถอนโคนคำถามตั้งแต่คุณตอบว่าคุณอาจพบว่ามันน่าสนใจและมีประโยชน์
terdon

นี่เป็นเรื่องจริงและตอนนี้ฉันก็ทำเช่นนี้ ;-)
pLumo

@ ทอมส์ก็โอเคที่จะรอสักครู่ (อาจจะเป็นวันหรือมากกว่านั้น) ที่จะยอมรับคำตอบแม้ว่ามันจะดีเท่านี้ เมื่อคำตอบได้รับการยอมรับก็ไม่มีทางที่คำตอบอื่นจะกลายเป็นสิ่งที่ดีกว่า และด้วยเหตุนี้ผู้คนจำนวนมากจะไม่รำคาญที่จะส่งคำตอบอื่น ๆ ดังนั้นเราจึงไม่ได้รับโอกาสที่จะเห็นพวกเขาเพื่อดูว่าดีขึ้นหรือไม่
Monty Harder

7

เนื่องจากคุณไม่ได้ระบุเชลล์เฉพาะนี่เป็นอีกทางเลือกหนึ่งโดยใช้ตัวระบุ glob ของ zsh ด้วย

setopt extendedglob

สำหรับการสอบถามซ้ำ ตัวอย่างเช่น:

  1. รายการไฟล์ธรรมดาซ้ำ:

    printf '%s\n' **/*(.)
  2. ซ้ำรายการไฟล์ธรรมดาo rdered โดยใน creasing L ength (เช่นขนาด):

    printf '%s\n' **/*(.oL)
  3. รายการซ้ำไฟล์ธรรมดาO rdered โดยเดอขนาด creasing:

    printf '%s\n' **/*(.OL)
  4. แสดงรายการไฟล์ธรรมดาซ้ำเรียงลำดับตามขนาดที่ลดลงและเลือกผลลัพธ์ 3 อันดับแรก:

    printf '%s\n' **/*(.OL[1,3])

หากคุณต้องการขนาดไฟล์ด้วยคุณสามารถใช้

du -hb **/*(.OL[1,3])

4

ด้วยglobstarชุดตัวเลือกเชลล์คุณสามารถใช้เชลล์กลม:

shopt -s globstar         # don’t match hidden files
shopt -s globstar dotglob # match hidden files
stat -c"%s %n" **/* | sort -n

หากคุณลองใช้ไฟล์ที่มีมากเกินไปคุณจะได้รับข้อผิดพลาด“ รายการอาร์กิวเมนต์ยาวเกินไป” ในการหลีกเลี่ยงปัญหานั้นคุณสามารถใช้printfและxargs:

printf "%s\0" **/* | xargs -0 stat -c"%s %n" | sort -n

ฉันเพิ่งรู้ว่านี่พิมพ์ไดเร็กตอรี่ (ที่มีขนาด 4096 ไบต์) เช่นกัน - หากคุณไม่ต้องการให้ใช้สิ่งนี้แทน:

stat -c"%A %s %n" **/* | sed '/^d/d;s/\S* //' | sort -n
printf "%s\0" **/* | xargs -0 stat -c"%A %s %n" | sed '/^d/d;s/\S* //' | sort -n

ตัวอย่างการวิ่ง

$ tree
.
├── edits.png
├── makescript
├── new
   └── edits.png
└── test
    └── 1.png

2 directories, 4 files
$ stat -c"%s %n" **/* | sort -n
0 test/1.png
43 makescript
2160 edits.png
2160 new/edits.png
4096 new
4096 test
$ stat -c"%A %s %n" **/* | sed '/^d/d;s/\S* //' | sort -n
0 test/1.png
43 makescript
2160 edits.png
2160 new/edits.png

ทางออกที่ดี เปรียบเทียบกับการค้นหาแล้วมันไม่รวมไฟล์ที่ซ่อนอยู่วิธีการทำเช่นนั้น?
pLumo

@RoVo ลืมสิ่งเหล่านี้เสมอ - คุณเพียงแค่ต้องตั้งค่าdotglobตัวเลือกเชลล์ดูคำตอบที่อัปเดตของฉัน
ของหวาน

แทนที่จะลอกไดเรกทอรีหลังจากข้อเท็จจริงด้วย sed คุณสามารถพิจารณาบางอย่างเช่นprintf "%s\0" **/* | xargs -0 sh -c 'for f; do [ -d "$f" ] || stat -c "%s %n" "$f"; done' sh | sort -n
steeldriver

คุณสามารถใช้ls -lhSd **/*ถ้าคุณไม่คิดว่าจะมีไดเรกทอรีเป็นส่วนหนึ่งของรายการ หรือถ้าไม่มีชื่อไดเรกทอรีของคุณมี.ในพวกเขาและไฟล์ทั้งหมดที่คุณต้องการทำคุณสามารถll -hS **/*.*หรือคล้ายกัน
Peter Cordes


3

หากคุณไม่มี zsh คุณยังสามารถใช้du+ sort:

  1. ขนาดที่มนุษย์อ่านได้รวมถึงขนาดสะสมของไดเรกทอรี:

    du --apparent-size -ah0 . | sort -zh | xargs -0L1
    
  2. เฉพาะไฟล์ (โดยใช้find):

    find . -type f -print0 |
      du --files0-from=- --apparent-size -ah0 |
      sort -zh |
      xargs -0L1
    

ในทั้งสองกรณีที่ผมได้เลือกที่จะใช้สายสิ้นสุดด้วย null ( -0, -z, -print0ตัวเลือก) เพื่อความปลอดภัยกับชื่อไฟล์ที่ถูกต้องทั้งหมด


0

สำหรับการใช้งานแบบอินเทอร์แอคทีฟอย่างรวดเร็วบนแผนผังไดเร็กทอรีที่ไม่ใหญ่เกินไปshopt -s globstarถือว่าดีมาก glob ไม่สามารถกรองไดเรกทอรีตามชนิด แต่ถ้าคุณใช้ด้วยls -dแล้วlsจะพิมพ์ชื่อไดเรกทอรีแทนเนื้อหา

สมมติว่าllชื่อแทนของคุณรวมถึง-lh:

  # with  shopt -s globstar   in your .bashrc
ll -rSd **/*

จะให้ผลลัพธ์เช่นนี้ (จากไดเรกทอรี code-golf ของฉัน) แต่มีการเน้นสี (เพื่อให้ง่ายต่อการดูไดเรกทอรี) โปรดทราบว่าการเรียงลำดับตามขนาดไฟล์เกิดขึ้นในไดเรกทอรีย่อย

drwxr-xr-x 1 peter peter   70 Jun  8 07:56 casexchg
...
drwxr-xr-x 1 peter peter  342 Mar 13 18:47 parity-party
-rw-r--r-- 1 peter peter  387 Jul 29  2017 likely.cpp
-rw-r--r-- 1 peter peter  416 Aug 31  2017 true-binary.asm~
-rw-r--r-- 1 peter peter  447 Feb 23 20:14 weight-of-zero.asm
...
-rw-r--r-- 1 peter peter 6.4K Jun  1  2017 string-exponential.asm
-rwxr-xr-x 1 peter peter 6.7K Aug 31  2017 true-binary
-rwxr-xr-x 1 peter peter 6.8K Sep 17  2017 dizzy-integer
-rw-r--r-- 1 peter peter 7.5K Jul 24  2017 fibonacci/fibonacci-1G.v3-working-32b-stack-except-output.asm
-rw-r--r-- 1 peter peter 8.4K Jul 25  2017 fibonacci/perf.32bit-pop-114limb.sub-cmc.1G~
-rw-r--r-- 1 peter peter 8.4K Jul 25  2017 fibonacci/perf.32bit-pop-114limb.sub-cmc.1G
-rwxr-xr-x 1 peter peter 8.4K May 19 04:29 a.out
-rw-r--r-- 1 peter peter 8.9K Jul 25  2017 fibonacci/perf.python-xnor-2n
-rw-r--r-- 1 peter peter 9.5K Jul 26  2017 fibonacci/fibonacci-1G-performance.asm
-rwxr-xr-x 1 peter peter 9.6K Apr 12 23:25 empty-args
-rw-r--r-- 1 peter peter 9.7K Dec 18 17:00 bubblesort.asm
-rwxr-xr-x 1 peter peter 9.9K Feb  6 23:34 parity-party/a.out
-rw-r--r-- 1 peter peter 9.9K Jul 25  2017 fibonacci/fibonacci-1G-performance.asm~
...

คุณสามารถกรองไดเรกทอรีโดยการไพพ์ grep -v '^d'

บางครั้งคุณสามารถใช้ glob ที่ตรงกับไฟล์เท่านั้นและไม่ใช่ไดเรกทอรีหากชื่อไฟล์ของคุณมีรูปแบบ เช่นll -rSd **/*.jpgหรือแม้กระทั่งการ**/*.*ทำงานถ้าไม่มีชื่อไดเรกทอรีของคุณมี.ในพวกเขาและไฟล์ทั้งหมดที่คุณต้องการจะทำ

(สำหรับผู้ที่มีพื้นหลัง DOS: ไม่มีอะไรมหัศจรรย์เกี่ยว*.*กับ Unix มันแค่ตรงกับรายการไดเรกทอรีใด ๆ ที่มีจุดตัวอักษร แต่นอกเหนือจากไฟล์ที่ปฏิบัติการได้และบางครั้งไฟล์ข้อความ

@dessert ชี้ให้เห็นว่าคุณต้องการshopt -s dotglobเพื่อให้ตรงกับไฟล์ทั้งหมด


ด้วย GNU find

หากไม่มีไฟล์มากเกินไปที่จะพอดีกับlsบรรทัดคำสั่งเดียวfind -exec ls {} +จะทำให้พวกเขาทั้งหมดในบรรทัดคำสั่งที่lsสามารถเรียงลำดับได้

find -not -type d -exec ls --color -lrSh {} +

การใช้-not -type dแทนการ-type fหลีกเลี่ยงการเชื่อมโยงสัญลักษณ์ที่มีชื่อว่าไพพ์ซ็อกเก็ตไฟล์อุปกรณ์และสิ่งอื่น ๆ ที่คุณได้ทำในไดเรกทอรีของคุณ


ด้วยdu:

du -ach | sort -h
....
4.0K    x86-modedetect-polyglot.o
8.0K    ascii-compress-base.asm
8.0K    dizzy-integer
8.0K    stopwatch-rdtsc.asm
8.0K    string-exponential.asm
8.0K    true-binary
12K     a.out
12K     bubblesort.asm
12K     casexchg
12K     empty-args
100K    parity-party
220K    fibonacci
628K    total

ตอนนี้ชื่อไดเรกทอรีจะถูกจัดเรียงลงในรายการด้วยเพื่อรวมผลรวมของเนื้อหาทั้งหมด แต่แต่ละไฟล์ยังคงรวมอยู่

sort -h, aka --human-numeric-sort, เรียงลำดับตัวเลขด้วยคำต่อท้ายขนาดเช่นdu -hภาพพิมพ์ duมันเหมาะสำหรับการใช้งานกับ

ฉันมักจะใช้du -sch * | sort -hหรือ*/เพื่อรับไดเรกทอรีเท่านั้น

du -sch **/* | sort -hจะให้ผลลัพธ์ข้างต้นถ้าคุณลืมว่าduมี-aตัวเลือก

(ผมเพียง แต่เอาเวลาที่จะมองมันได้เพราะผมโพสต์คำตอบ. du -sch **/*สำหรับการใช้งานแบบโต้ตอบผมก็อาจจะมีการใช้เพียง

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