Мне бы хотелось написать сценарий bash, который поможет мне найти возможности сокращения использования диска.
Скрипт принимает 2 аргумента: родительскую папку (у меня это обычно /apps/
) и порог (например, «200M»).
Мой текущий подход не идеален (не использует порог и показывает много избыточного вывода).
В настоящее время я запускаю cd /apps/ && du -aBM 2>/dev/null | sort -nr | head -n 15
и вижу вывод вроде:
8975M .
1448M ./delta
1387M ./alpha
1350M ./alpha/releases
1144M ./bravo/releases
1144M ./bravo
1137M ./charlie
1117M ./delta/releases
902M ./alpha/releases/202210091311
871M ./charlie/releases
796M ./echo
794M ./echo/releases
791M ./alpha/releases/202210091311/node_modules
703M ./scoreboard
684M ./scoreboard/node_modules
Я бы хотел, чтобы в выводе были пропущены такие строки, как:
8975M .
1448M ./delta
1387M ./alpha
1350M ./alpha/releases
1144M ./bravo
1137M ./charlie
902M ./alpha/releases/202210091311
796M ./echo
703M ./scoreboard
потому что это была пустая трата моего внимания, поскольку приведенные выше выходные данные также включали подпапки тех папок, которые были выше порогового значения, которое меня волнует (200M).
Вот наиболее интересные строки:
1144M ./bravo/releases
1117M ./delta/releases
871M ./charlie/releases
794M ./echo/releases
791M ./alpha/releases/202210091311/node_modules
684M ./scoreboard/node_modules
Однако я не думаю, что подход du -aBM 2>/dev/null | sort -nr
— правильная отправная точка для достижения моей реальной цели.
Потому что на самом деле, возможно, любая из этих папок (в моем последнем примере) даже не настолько вложена/глубока, как могла бы быть (подпапки самого низкого уровня, которые также удовлетворяют порогу в 200 МБ).
Например, возможно, /echo/subfolder1
и /echo/subfolder2
равны 300M каждый.
У меня есть облачный сервер с ограниченным дисковым пространством, и я не хочу платить за него больше.
Более целесообразно искать 1% файлов с наибольшим размером в крупнейших каталогах, и для этого существуют инструменты. Видеофайлы высокого разрешения занимают много места. Дисковое пространство теперь стоит дешево, поэтому, если оно действительно не заканчивается, о нем больше не стоит беспокоиться. Время от времени удалять несколько ненужных огромных файлов вполне достаточно.
@JohnGordon Исправлено, спасибо.
@MartinBrown Лично я не предпочитаю тратить деньги на хранение файлов, которые мне не нужны. Это законный технический вопрос, который мне интересен, и я бы хотел, чтобы люди не голосовали за него. Я уже рассматривал инструменты анализа хранилища, такие как ncdu
, они классные, но недостаточно удобные.
Когда я сравниваю список того, что вам не нравится, и список того, что вам нравится, я не вижу никакой разницы (очевидно, она может быть и для вас, но я ее не вижу). Пока вы не способны провести четкое различие между вещами, которые вам нравится видеть, и остальными, как вы объясните это своему компьютеру? :-)
@Dominique Две строки, в которых я пытался описать это различие, были: because those were a waste of my attention since the output above had also included subfolders of those folders that were above the threshold that I care about
и in reality, maybe any of those folders (in my most recent example) aren't even as nested / deep as they could be (the lowest level subfolders that also satisfy the threshold of 200 MB).
Я мог бы попытаться написать это еще яснее, но я старался быть кратким, поскольку сообщество StackOverflow, к сожалению, предпочитает краткость даже в ущерб ясности.
Иерархия каталогов — это дерево. Его узлами являются каталоги и файлы. Для файлов значением узла является его размер. Для каталогов значение узла представляет собой сумму размеров всех его дочерних элементов. Я считаю, что данная проблема состоит в том, чтобы выбрать узлы со значением, превышающим некоторый порог, все дочерние элементы которых меньше этого порога.
Как выбрать 15 крупнейших из них, уже известно.
Удобно, что du -a
автоматически обеспечивает поступорядочение поиска в глубину дерева.
Итак, решение проблемы — пройтись по выходу du
.
Это работает, поскольку поступорядочение означает, что немаркированный путь, превышающий пороговое значение, не может иметь меньших дочерних элементов.
Предполагая, что пути не начинаются с пробелов и не содержат символов новой строки:
du -aBM /apps/ 2>/dev/null |
awk -F/ -v OFS=/ -v min=200 '
$1+0 > min {
raw = $0
sub(/^[0-9]+M[ \t]+/,"") # strip size
sub(//+$/,"") # strip trailing slashes
if ($0 in seen) next
print raw
# mark ancestors as seen
s = $1
for (f=1; f<NF; s = s OFS $(++f))
seen[s]
}
' |
sort -rn | head -15
Ответ du -S
с пользой решает немного другую связанную проблему, где значение узлов каталога представляет собой сумму размеров дочерних элементов, которые являются файлами, и выбираются только узлы каталога.
Это выглядит великолепно и кажется, что это может быть правильно! Спасибо! P.S. Было бы еще лучше отсортировать окончательный результат по убыванию размера. Наверное, я смогу придумать, как это сделать.
Вот хотя бы начало (сейчас нет времени дорабатывать его, чтобы избавиться от "./charlie" и преобразовать размеры файлов в байты для окончательного сравнения):
$ cat tst.sh
#!/usr/bin/env bash
sort -k2 "${@:--}" |
awk '
{
dir = $0
sub(/^[^[:space:]]+[[:space:]]+/,"",dir)
}
index(dir,prev"/") == 1 {
delete dirs[prev]
}
{
dirs[dir] = $0
prev = dir
}
END {
for ( dir in dirs ) {
print dirs[dir]
}
}
' |
sort -rn
$ cat file | ./tst.sh
1350M ./alpha/releases
1144M ./bravo/releases
1137M ./charlie
1117M ./delta/releases
871M ./charlie/releases
794M ./echo/releases
791M ./alpha/releases/202210091311/node_modules
684M ./scoreboard/node_modules
Замените cat file
командой du
из вопроса.
Первая строка вашего вывода — это alpha/releases
, которую ОП указал как нежелательную. Это связано с тем, что он содержит 1350 МБ, а один из его подкаталогов содержит 791 МБ, поэтому максимум, который он может содержать в простых файлах, составляет (1350-791) = 559 МБ, что немного.
@ k314159 k314159, как я уже упоминал в своем ответе, «вот начало...». Здесь показан типичный подход к решению подобных проблем: сначала сортировка по пути, отбрасывание родительских каталогов, а затем сортировка по размеру.
Похоже, опция du -S
— это именно то, что вы ищете:
$ du --help
...
-S, --separate-dirs for directories do not include size of subdirectories
...
$ du -SBM | sort -nr | head -n 15
Приведенная выше команда должна предоставить вам список из 15 крупнейших каталогов, не считая подкаталогов. Регулируйте число head -n
, пока не достигнете желаемого порога.
(Также обратите внимание, что я опустил параметр du -a
, поскольку вы не хотите, чтобы размеры отдельных файлов смешивались с размерами каталогов, поскольку это привело бы к дублированию информации.)
Интересный альтернативный подход. Он не будет объединять небольшие ветки и показывать их, когда общее количество превышает пороговое значение, но это может не быть проблемой.
Это выглядит интересно. Действительно простая команда. Хотя я не понимаю эту строку из справочной документации. Я только что протестировал его и не думаю, что он полностью достигает того, о чем я просил, но его легче запомнить, и он полезен в крайнем случае, потому что он помогает мне находить большие папки. Спасибо.
@Райан, что означает эта строка из справочной документации: например, если каталог содержит файлы общим размером 100 МБ, а также содержит подкаталог, который, в свою очередь, содержит 50 МБ файлов, то опция -S
покажет размер каталога как 100 МБ, потому что он исключает подкаталог. Без опции -S
будет отображаться 150 МБ, поскольку по умолчанию он включает подкаталоги.
О, теперь я понимаю. Спасибо!!
796M ./echo
Эта строка есть и в списке «пропустить», и в списке «интересно»...