Странное поведение с находкой и - PullRequest
1 голос
/ 02 февраля 2020

Я пытаюсь сгенерировать пользовательское использование в определенных папках в сценарии оболочки и обнаружил странное поведение с моей комбинацией find и du.

У меня есть папка с ~ 9500 файлами в общей сложности 5 ГБ. 4 ГБ этой папки состоит из 7 больших файлов, а оставшийся 1 ГБ состоит из небольших файлов (около 9000 из них). У меня проблема в том, что мой скрипт, кажется, игнорирует большую часть файлов, поэтому общее использование, о котором сообщает du, неверно.

В строке ниже указано правильное число для общего количества файлов (+ 1 для общего числа):

$ find . -type -f -exec du -ch {} + | wc -l
9596

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

$ find . -type -f -exec du -ch {} + 
...lines of files
139M total < this value is incorrect, should be ~5GB

Если я ограничу размер до большие файлы (более 25 МБ), он действительно берет большие файлы и приближается, но, очевидно, отсутствует то много маленьких файлов, которые составляют оставшийся 1 ГБ.

$ find . -type -f -size +25M -exec du -ch {} + 
561M    ./largefile0
483M    ./largefile1
514M    ./largefile2
948M    ./largefile3
360M    ./largefile4
768M    ./largefile5
764M    ./largefile6
4.3G    total < this is the correct total for these files

Наконец, даже более странно, если я запускаю снова введите команду без параметра размера и затем grep для large. Она подберет файлы largefile[0-6].

$ find . -type -f -size +25M -exec du -ch {} + | grep large
561M    ./largefile0
483M    ./largefile1
514M    ./largefile2
948M    ./largefile3
360M    ./largefile4
768M    ./largefile5
764M    ./largefile6

Так что я не совсем уверен, что здесь происходит, как будто существует ограничение к числу файлов, которые du может сообщить, это его общее количество, но оно всегда равно 139M для этого набора данных.

1 Ответ

1 голос
/ 02 февраля 2020

Не понятно, о чем вы спрашиваете. Если это просто объяснение результата, то:

предикат -exec {} + не выполняется только один раз, он имеет ограничение по размеру, при достижении которого команда выполняется и новая "команда" начинает см.: https://git.savannah.gnu.org/cgit/findutils.git/tree/find/exec.c#n153

На моем компьютере этот размер составляет ~ 128 КБ.

$ find ./ -type f -name 'file*' -exec echo {} + 2>/dev/null | head -1 | wc -c
131056

Для примера каталога, содержащего около 40000 файлов, команда выполняется 7 раз.

$ find ./ -type f -name 'file*' -exec echo {} + | wc -l
7

Если я ограничу количество файлов, оно уместится в один:

$ find ./ -type f -name 'file5*' -exec echo {} + | wc -l
1

Если вы хотите получить итоговый размер файла:

find ./ -type f -name 'file*' -exec du -ck {} + | awk ' $2 == "total" { T+=$1 } END { print T } '

обратите внимание, что я использовал k вместо h, чтобы убедиться, что все результаты имеют одинаковый порядок величины.

...