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


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 */ .[^.]*/; до ... `
Оливье Дюлак

Ответы:


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 следовали символическим ссылкам при спуске дерева каталогов.


Спасибо, это работает! Я ценю помощь. Я пытаюсь привыкнуть к программированию в оболочке. Я не очень много знаю сейчас, поэтому я ценю, что вы рассказали мне, что происходит с этой строкой кода.
user2419571

Быстрый вопрос: из любопытства есть ли способ сделать это, не передавая команды? Мне любопытно, потому что каждый пример, который я видел, использовал какой-то трубопровод.
user2419571

2
Я уверен, что есть другие способы сделать это. Философия UNIX заключается в том, что инструменты должны быть одноцелевыми и объединять их так, чтобы выходные данные одной команды подавались на вход следующей.
Гленн Джекман

В этом есть смысл. Еще раз спасибо за вашу помощь.
user2419571

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
Этот ответ можно улучшить, объяснив, как он работает. Кроме того, это выглядит очень похоже на принятый ответ (который не полностью объясняет, как он работает).
Дхаг

man findи man sortиспользуйте brainz :-)
CeDeROM

На самом деле не работает на MacOS, так как он не может правильно вернуть размер и возвращает огромное количество столбцов.
Сорин

3

С zsh, для самого большого регулярного файла:

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

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

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

Если есть связи, вы получите любой из них наугад. Если вы хотите первый в алфавитном порядке, добавьте дополнительный on( order by name) для сортировки связей в алфавитном порядке.

Обратите внимание, что он учитывает размер файлов, а не использование диска.


... Я начинаю верить, что вы на зарплате Zsh;) (что это очень хорошо может быть?). К сожалению, zsh доступен не во всех системах ...
Olivier Dulac

Можно ли получить первые десять файлов? (Не делая глупостей вроде петли)
Wowfunhappy

1
@Wowfunhappy заменить [1]на[1,10]
Стефан Шазелас
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.