Если вы используете инструменты GNU (, которые являются стандартными для Linux ), вы можете сделать что-то вроде этого:
stat --printf '%s\t%n\0'./* |
sort -z -rn |
head -z -n 5 |
cut -z -f 2- |
xargs -0 -r echo rm -f --
(удалите "эхо" после того, как вы протестировали его ).
Команда stat
выводит размер файла и имя каждого файла в текущем каталоге, разделенные табуляцией, и каждая запись завершается байтом NUL (\0 ).
Команда sort
сортирует каждую запись с завершением NUL -в обратном числовом порядке. Команда head
выводит только первые пять таких записей, затем cut
удаляет поле размера файла из каждой записи.
Наконец, xargs
принимает этот (все еще NUL -завершенный )ввод и использует его в качестве аргументов для echo rm -f
.
Поскольку в качестве терминатора записи (имени файла )используется NUL, он работает с именами файлов, содержащими любой допустимый символ.
Если вам нужен минимальный размер файла, вы можете вставить awk
или что-то между stat
и sort
. например.
stat --printf '%s\t%n\0'./* |
awk 'BEGIN {ORS = RS = "\0" } ; $1 > 25000000' |
sort -z -rn |...
ПРИМЕЧАНИЕ. :GNU awk
не имеет опции -z
для записей с завершением NUL -, но позволяет вам установить разделитель записей на любое значение, которое вы хотите. Мы должны установить для разделителя выходных записей (ORS )и разделителя входных записей (RS )значение NUL.
Вот еще одна версия, которая использует find
для явного ограничения себя обычными файлами (, т.е. исключая каталоги, именованные каналы, сокеты и т. д. )только в указанном каталоге (-maxdepth 1
, без подкаталогов )] размером более 25M (нет необходимости вawk
).
Эта версия не нуждается в stat
, потому что GNU find
также имеет функцию printf
. Кстати, обратите внимание на разницу в строке формата-stat
использует %n
для имени файла, а find
использует %p
.
find. -maxdepth 1 -type f -size +25M -printf '%s\t%p\0' |
sort -z -rn |
head -z -n 5 |
cut -z -f 2- |
xargs -0 -r echo rm -f --
Чтобы запустить его для другого каталога, замените .
в команде find. например.find /home/web/....
версия сценария оболочки:
#!/bin/sh
for d in "$@" ; do
find "$d" -maxdepth 1 -type f -size +25M -printf '%s\t%p\0' |
sort -z -rn |
head -z -n 5 |
cut -z -f 2- |
xargs -0 -r echo rm -f --
done
сохраните его как, например, delete-five-largest.sh
где-нибудь в вашем PATH и запустите какdelete-five-largest.sh /home/web /another/directory /and/yet/another
Это запускаетfind...
один раз для каждого каталога , указанного в командной строке. Это НЕ то же самое, что и однократный запуск find
с несколькими аргументами пути (, который будет выглядеть как find "$@"...
, без какого-либо for
цикла в сценарии ). Он удаляет 5 самых больших файлов в каждом каталоге, а его запуск без цикла for удалит только пять самых больших файлов, найденных при поиске во всех каталогах. то есть пять на каталог против пяти всего.
Ловушка вызывается после каждой установленной командной строки. Как показано с помощью вывода TRACE ниже:
+ badvar=0
+ set -o functrace
+ trap dbgtrap DEBUG
++ dbgtrap
++ echo 'badvar is 0'
badvar is 0
+ some_func
++ dbgtrap
++ echo 'badvar is 0'
badvar is 0
++ dbgtrap
++ echo 'badvar is 0'
badvar is 0
+ badvar=1
++ dbgtrap
++ echo 'badvar is 1'
badvar is 1
+ badvar=2
++ dbgtrap
++ echo 'badvar is 2'
badvar is 2
+ badvar=3
++ dbgtrap
++ echo 'badvar is 3'
badvar is 3
+ trap - DEBUG
Оболочка IIRC вызывает ловушку в конце обработки, поэтому 3 строки вывода перед вызовом функции выводят значения badvar.