Oracle Linux 6.7 -bash: /usr/bin/du: Слишком длинный список аргументов

Oracle Linux 6.7 -bash: /usr/bin/du: Слишком длинный список аргументов

У меня есть путь из примерно 1 миллиона папок общим размером 300 ГБ. Когда я запускаю команду du -sh *, я получаю ошибку, которую я упомянул в заголовке. Как мне объединить использование xargsс этой командой или это xargsрешит мою проблему? Однако мне все еще нужна отдельная команда для поиска папок размером более 20 ГБ по тому же пути. Нужна помощь по использованию этих двух команд.

Пример пути:/data/dataold/exports/

Вывод должен быть таким, как показано ниже (Вы можете воспринимать то, что я указал ниже, как имена файлов и папок по основному пути, который я указал в строке выше):

4.0K xyz.sh
12K asdasda.txt
10G QWERT
1G ASDFGH

С наилучшими пожеланиями.

решение1

Одним из вариантов является использование find, но я предлагаю одно из других решений, показанных ниже.

find /data/dataold/exports -mindepth 1 -maxdepth 1 -exec du -sh {} \;

Предполагая, что /data/dataold/exportsсодержит подкаталоги

foo
bar
baz

(а может и больше), он будет работать

du -sh /data/dataold/exports/foo
du -sh /data/dataold/exports/bar
du -sh /data/dataold/exports/baz

и т. д.

Параметр -mindepthпозволяет избежать запуска duкоманды для /data/dataold/exports, а также -maxdepthдля подкаталогов подкаталога, например, для /data/dataold/exports/foo/something.

Как предложено вкас' комментарий, вы можете использовать

find /data/dataold/exports -mindepth 1 -maxdepth 1 -exec du -sh {} \+

вместо ... -exec du -sh {} \;, если ваша версия findподдерживает это. С +вместо ;, findбудет выполняться duодин раз для каждого заполнения буфера аргументов linux (примерно 2 МБ) вместо того, чтобы выполнять его один раз для каждого файла/каталога. Первый вариант —многоБыстрее.

СсылаясьСтефан Шазелас' комментарий: "Обратите внимание, что вызов нескольких независимых вызовов du(например, с помощью find -exec) может дать разные числа, если в этих каталогах верхнего уровня есть жесткие ссылки, поскольку они не будут дедуплицированы, если будут найдены разными вызовами du."


С помощью GNU duвы можете ограничить глубину отображения с помощью option -dили --max-depth=N:

du -h -d 1 /data/dataold/exports

Это выполнит расчет для всех подкаталогов, но ограничит вывод глубиной на 1 ниже начальной точки, поэтому в примере, показанном выше, он должен вывести общий размер для

/data/dataold/exports/foo
/data/dataold/exports/bar
/data/dataold/exports/baz

и т.д. и для

/data/dataold/exports

Второе решение, если оно доступно, следует предпочесть, поскольку оно не требует запуска нового duпроцесса для каждого подкаталога (в случае -exec ... \;) или для каждого набора подкаталогов, заполняющих буфер аргументов (в случае -exec ... \+).

Если ваша версия duне поддерживает опцию, -dвы можете использовать

du -h /data/dataold/exports

и отфильтровать вывод, чтобы удалить все, что находится ниже первого уровня подкаталогов.


Если вы хотите отфильтровать вывод по числовому сравнению, я предлагаю опустить опцию -h. Чтобы избежать ожидания медленного доступа к файловой системе при тестировании фильтрации, я предлагаю перенаправить вывод в файл, например

du -d 1 /data/dataold/exports > outputfile

или

du -d 1 /data/dataold/exports 2>errors | tee outputfile

и обработать содержимое outputfileпозже.

Пример:

awk '$1 > 20e9` outputfile

Если ваш duвариант не поддерживается, -dвы можете использовать что-то вроде

du /data/dataold/exports > outputfile
awk '$1 > 20e9 && $1 != /\/.*\/.*\/.*\/.*\/.*/` outputfile

Это выведет все строки, которые имеют число больше 20 * 10^9 в первом поле и значение, которое не содержит 5 (или более) слешей во втором поле. Количество слешей во втором условии подбирается в зависимости от начального каталога /data/dataold/exportsи выведет eg, /data/dataold/exports/fooно не eg /data/dataold/exports/foo/bar.

решение2

Постарайтесь не обобщать, а затем позвольте duработе быть выполненной. Подайте заявку sortс -human order, затем установите предел определенного размера:

du -h /data/dataold/exports/ | sort -h

используйте для перечисления в обратном порядке, т.е. от больших файлов к меньшим -r.sort

Для выбора размера awkподойдет простой трюк:

du -h /data/dataold/exports/ | awk -F'G' '$1~/^[0-9]+$/ && $1>=20' | sort -h 

То есть: использовать G(из вывода размера ГБ) в качестве разделителя полей, проверить, является ли поле только числом (чтобы исключить неправильные совпадения с G-разделителем), а затем выбрать только числа больше 20. Сортировка здесь необязательна.

Связанный контент