
Я хотел бы удалить определенное количество самых больших файлов в каталоге.
Я могу получить имена файлов первых десяти с помощью:
ls -S | head
(или более богатый, хотя и более сложный для анализа ls -lS | head
)
Как мне передать их в rm? через xargs?
Так будет ли ls -S | head | xargs rm
работать (даже с именами файлов с пробелами и т.п.)?
Есть ли лучший/более безопасный способ?
Извините, но я не смог проверить это сам, опасаясь оплошать (в каталоге есть вещи, которые я действительно не хочу удалять).
Я использую macOS.
решение1
Так будет ли
ls -S | head | xargs rm
работать (даже с именами файлов с пробелами и т.п.)?
Нет. xargs
по умолчанию разделяет по любому пробелу, а не только по новой строке. И вы не можете увидеть это с помощью | xargs echo
, поскольку echo
печатает все свои аргументы, разделенные пробелами. (Что-то вроде | xargs printf "%s\n"
печатало бы их разделенными новой строкой, так что вы увидите, происходит ли разделение в середине имени файла.)
По крайней мере GNU xargs должен -d '\n'
разделяться только по символам новой строки, а многие версии xargs должны -0
разделяться по символам NUL (это идет с find -print0
). Вам понадобится по крайней мере первый, но в общем случае имена файлов могут также содержать новые строки, в этом случае head
тоже не будет много пользы.
Я обязан предупредить вас, чтосинтаксический анализ вывода ls
считается неправильным, по-видимому, по крайней мере некоторые версии будут искажать вывод даже без наличия новых строк. (Хотя вы можете быть в безопасности, если у вас нет новых строк или непечатаемых символов. Возможно.)
решение2
Я бы использовал другой подход. Что-то вроде этого:
size=20000 # set a limit (in bytes), above these we will delete
for file in *
do
[[ -f "$file" ]] || continue
fileSize=$(stat --format "%s" "$file")
if (( $fileSize > $size )) # if file is bigger than 20000 bytes
then
rm "$file" # delete the file
fi
done
Таким образом, вы сможете удалять файлы с пробелами и сможете решать с помощью $size
переменной, какие файлы на самом деле "большие". Если вы хотите получать запрос перед каждым удалением, используйте переключатель -i
:rm -i
Редактировать:
Я только сейчас понял, что вы используете это под OS X. У меня сейчас нет доступа к какой-либо машине с OS X, может быть риск, что stat
у OS X другой формат для получения размера. Другими словами, эта --format "%s"
опция может не работать. Проверьте man stat
в OS X!
решение3
Я бы выбрал;
find . -type f -size +10M -delete -print
Если вы действительно хотите пойти по пути ls, возможно;
ls -S | head -1 | while read af; do rm "$af"; done
решение4
Использоватьзш. Он имеет метод сортировки и выбора файлов по размеру (и по дате, что используется чаще). Zsh является частью стандартной установки на OSX/macOS, но может потребоваться отдельная установка на других вариантах Unix.
Способ выбора (и сортировки) файлов с использованием критериев, отличных от имени, следующий:квалификаторы glob. Например, чтобы составить список 10 самых больших файлов в каталоге, используйте OL
сортировку по убыванию размера (лength) и [1,10]
перечислить первые 10:
ls -ldU *(OL[1,10])
Делать это без zsh сложнее, особенно если вам нужно справиться с именами файлов, содержащими специальные символы. Пока имена ваших файлов не содержат непечатаемые символы или символы новой строки, вы можете разобрать вывод ls
.
ls -S | head -n 10 | while read -r filename; do echo rm -- "$filename"; done