Я хочу найти все папки (в папке) размером менее 100 МБ и удалить их. Я на самом деле не хочу использовать скрипт bash. Но, вероятно, есть некоторая изящная возможность в одну строку сделать это. Но, к сожалению, мои знания оболочки не так хороши
То, что я пробовал
du -sh * | grep -E "^[0-9]{1,2}M" | xargs -0 rm
Это не сработает, поскольку вывод du -sh * | grep _E ".."
выглядит как одна строка.
Я также попробовал
find . -maxdepth 1 -type d -size 100M [-delete]
Но я думаю, что флаг -size
- это не то, что я ищу
Используя du
с флагом -h
, чтобы сделать сравнение значения обычно является плохой идеей.
команда, которую Вы ищете:
find . -maxdepth 1 -type d | grep -v ^\\.$ | xargs -n 1 du -s | while read size name ; do if [ $size -gt 104857600 ] ; then echo rm -rf $name ; fi done
Объяснение:
find . -maxdepth 1 -type d
находит, что все подкаталоги текущего каталога grep -v ^\\.$
исключают текущий каталог (.) xargs -n 1
, передает их один за другим следующей команде du -s
, предоставляет сводку (т.е. общее количество), пространство файлов в том каталоге while read size name
... done
выполняет цикл по своему входу, читая размер и название каждого каталога , Как только Вы довольны командой, удаляют echo
прежде rm -rf
Простой подход должен найти все каталоги, получить их размер и удалить их, если они находятся под данным порогом:
find . -maxdepth 1 -type d |
while read dir; do [ $(du -s "$dir") -le 102400 ] && rm -f "$dir"; done
Однако, который перестанет работать на именах каталогов, содержащих новые строки или другие странные символы. Более безопасный синтаксис:
find . -maxdepth 1 -type d -print0 | while IFS= read -r -d '' dir; do
[ $(du -s "$dir") -le 102400 ] && rm -f "$dir"
done
, Так как это обработает подкаталоги перед их родителями, к тому времени, когда dir1
обрабатывается, dir2
и dir3
будет уже удален так, его размер будет ниже порога, и он также будет удален. Хотите ли Вы на самом деле, это будет зависеть от того, что точно Вы пытаетесь сделать.
Это, однако, является упрощенным подходом. Рассмотрите следующий сценарий:
$ tree -h
.
`-- [4.0K] dir1
|-- [4.0K] dir2
| `-- [ 80M] file1
`-- [4.0K] dir3
`-- [ 80M] file2
3 directories, 2 files
Здесь, у нас есть 2 подкаталога под dir1
, каждый содержащий 80M файл. Команда выше сначала найдет dir1
, чей размер> 100M, таким образом, это не будет удалено. Это тогда найдет dir1/dir2
и dir1/dir3
и удалит их обоих, так как они - < 100M. Конечным результатом будет пустое dir1
, чей размер, конечно, будет < 100M, так как это пусто.
Так, это решение будет хорошо работать, если у Вас только будет единственный уровень подкаталогов. Если у Вас есть более сложные файловые структуры, необходимо думать о том, как Вы хотите иметь дело с этим. Один подход должен был бы использовать -depth
, который гарантирует, что подкаталоги показывают сначала:
find . -depth -maxdepth 1 -type d -print0 | while IFS= read -r -d '' dir; do
[ $(du -s "$dir") -le 102400 ] && rm -f "$dir"
done
Таким образом, dir1
будет обработан после dir2
и dir3
, таким образом, это будет пусто, приведет порог к сбою и будет удалено также. Хотите ли Вы, это будет зависеть от того, что точно Вы пытаетесь сделать.