Удаление некоторых самых больших файлов в каталоге

Удаление некоторых самых больших файлов в каталоге

Я хотел бы удалить определенное количество самых больших файлов в каталоге.

Я могу получить имена файлов первых десяти с помощью:

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

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