Найти самые старые файлы / каталоги в файловой системе до 50 ТБ

8

Мне нужно найти самые старые файлы с соответствующими каталогами в файловой системе объемом 90 ТБ до 50 ТБ, а затем переместить их в другую файловую систему. Они должны сохранять свою структуру каталогов, так как именно это определяет файлы. Так -

первый уровень / второй уровень / третий уровень / (файл)

это структура. Мне нужно переместить всю эту структуру - в каталогах верхнего уровня ничего нет, но без них я не могу определить, к какому файлу относится, так как все файлы, которые я ищу, имеют одинаковые имена. Когда процесс будет завершен, у меня должно остаться примерно 40 ТБ в исходной файловой системе и почти ничего в новой файловой системе не останется, поскольку самые старые файлы в оригинале уже есть.

Спасибо!

J Telep
источник

Ответы:

9

С инструментами GNU и rsync, вы можете сделать:

export LC_ALL=C # force tools to regard those file paths as arrays
                # of bytes (as they are in effect) and not do fancy
                # sorting (and use English for error/warning messages 
                # as an undesired side effect).

find . -type f -printf '%T@/%s/%p\0' | # print mtime/size/path
  sort -zn | # numerical sort, oldest first
  awk -v RS='\0' -v ORS='\0' -F / -v max=50e12 '
    {total_size += $2}
    total_size > max {exit}
    {
      sub("^[^/]*/[^/]*/", "") # remove mtime/size/
      print # path
    }' |
  rsync -nv -aHAX0 --files-from=- --remove-source-files . /dest/dir/

(непроверенный. Это -nдля всухую. Удалите, если счастлив).

Обратите внимание, что мы рассчитываем совокупный размер файла, основываясь на размерах файлов ( %sзаменим %bна использование диска в секторах (и изменим на total_size += $2 * 512) и игнорируем жесткие ссылки. Эти файлы при копировании в целевую файловую систему вместе с каталогами содержащие их, вероятно, в конечном итоге будут использовать более 50 ТБ (если только в файловой системе не выполняется сжатие или дедупликация).

Стефан Шазелас
источник
1
Ответ лучше, чем мой (хотя я бы добавил total_size > max { exit 0 }к сценарию awk)
symcbean
@ Symcbean, хорошая мысль! Я добавил это сейчас. Спасибо.
Стефан
Это выглядит великолепно! Однако возникает один вопрос - я предполагаю, что часть «max = 50e12» в выражении awk диктует системе, что мы хотим 50 ТБ, поэтому на основе дополнительных папок (так как для каждого файла есть две), если бы мне было нужно, я мог бы уменьшить что от "50" до "49" и что будет равно 49 ТБ?
J
1
@JTelep, это научная запись. 50e12 - это 50 раз от 10 до мощности 12, то есть 50 ТБ (не 50 ТБ, для которых вам нужно 50 * 2^40). Вы также можете изменить его, total_size += $2 + overheadгде overheadон определяется как издержки, связанные с этими папками. Смотрите также %kвместо того, %sчтобы получить использование диска в КиБ.
Стефан
2

Команда 'ls' несколько креативна с временными метками, поэтому их анализ может быть болезненным. Вероятно, было бы намного проще реализовать это на языке, который реализует stat (). В некоторых версиях Unix есть статистика командной строки - в соседнем окне RH:

 find ${BASEDIR} -type f -exec stat --format="%y %b %n" {} \; | sort | less

Но это будет работать как собака с большим количеством файлов.

Документация для GNU awk включает в себя пример расширения, предоставляющего функции файловой системы, но вам нужно будет поработать, чтобы создать и поддерживать его.

Написание программы с нуля на PHP, C или Perl (или go, ruby ​​или многих других языках) будет простым, но выходит за рамки поста здесь.

symcbean
источник
1
Обратите внимание, что этот GNU statбыл добавлен задолго после того, как у GNU findбыла -printfкоманда (которая может делать то же самое, что и GNU statс гораздо лучшим интерфейсом).
Стефан