Пошук найбільшого файлу рекурсивно


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 */ .[^.]*/; do ... `
Олів'є Дулак

Відповіді:


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

Швидке запитання: з цікавості є спосіб зробити це без трубних команд? Мені цікаво, тому що кожен приклад, який я бачив, використовував якісь трубопроводи.
user2419571

2
Я впевнений, що є й інші способи зробити це. Філософія UNIX полягає в тому, що інструменти повинні бути одноцільовими та об'єднати їх у ланцюг, щоб вихід однієї команди надходив на вхід наступної.
glenn jackman

Що має сенс. Ще раз дякую за допомогу.
користувач2419571

2
@ user2419571:; tail -n 1 <(sort -n <(find . -type f -printf "%s\t%p\n")))
Сайрус


5

Це працює на BSD / macOS:

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

Ви також можете додати | head -n 3до відображення кількості цікавих записів (3 у цьому випадку).


1
Цю відповідь можна було б покращити, пояснивши, як вона працює. Крім того, він дуже схожий на прийняту відповідь (яка також не повністю пояснює, як вона працює).
dhag

man findі man sort, використовуйте brainz :-)
CeDeROM

Насправді не працює MacOS, оскільки він не може правильно повернути розмір і повертає величезну кількість стовпців.
sorin

3

З zsh, для найбільшого звичайного файлу:

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

(звичайно, ви можете замінити ls -ld --будь-яку команду. Якщо ви використовуєте GNU lsабо сумісні, див. також -hопцію для людських читаних розмірів )

  • .: лише звичайні файли (не каталоги, посилання, пристрої, файли ...)
  • D: включіть приховані та спустіться в приховані бруди
  • OL: зворотній упорядкований розмір ( Lангл.)
  • [1]: тільки перший матч.

Якщо є зв’язки, ви отримаєте будь-який з них навмання. Якщо ви хочете, щоб перший був в алфавітному порядку, додайте додатковий on( order by name), щоб сортувати зв'язки за алфавітом.

Зауважте, що він враховує розмір файлів, а не використання диска.


... я починаю вірити, що ви перебуваєте на зарплаті zsh;) (що це дуже добре могло б бути?). zsh, на жаль, доступний не для всіх систем ...
Олів'є Дулак

Можливо отримати перші десять файлів? (Не роблячи чогось дурного, як петля)
Wowfunhappy

1
@Wowfunhappy замінити [1]на[1,10]
Stéphane Chazelas
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.