Удалите все файлы в папке, кроме последней (последней) 20

Я хочу удалить все файлы из разных каталогов и хочу сохранить только последние файлы 20 файлов. это правильная команда для этого?

ls -t1 /mnt/dwh/ftp/dwh_ftp_cbs/ARLOGS/ | tail -n +22 | xargs rm -f 

2 Solutions collect form web for “Удалите все файлы в папке, кроме последней (последней) 20”

В вашей команде есть много недостатков, например обработка вывода ls , это своего рода катехизис. См. Эту статью, почему бы не сделать это.

Этот подход не использует расширения GNU и проверяется на bash, zsh, ksh93, тире и золе:

 for f in * .*; do [ -f "$f" ] && printf "%s " $(perl -e 'print((stat("$ARGV[0]"))[9])' -- "$f") && \ printf "%s\0" "$f"; done | tr '\0\n' '\n\0' | sort -k1nr | \ sed "1,20d;s/'/'\"'\"'/g;s/[^ ]* \(.*\)/rm -f -- '\1';/" | tr '\0' '\n' | sh 

Это самое странное имя файла, которое я смог произвести, он работает даже с этим:

 touch -- '--a'"'"'b"c d$e\nf\r!g;h^i`j(k)l*m%n=o?p.txt' 

Или имя файла, которое пытается «выпрыгнуть»:

 touch '\'"'"'echo test '"'"'\' 
 ls -t1 /mnt/dwh/ftp/dwh_ftp_cbs/ARLOGS/ | tail -n +22 | xargs rm -f 

Не будет работать, потому что вывод ls будет включать имена файлов, а не их полный путь. Он также пропустит файлы, имя которых начинается с . ,

 cd /mnt/dwh/ftp/dwh && ls -At1 | tail -n +21 | xargs rm -f -- 

разрешит это, но у вас все еще будут проблемы с именами файлов, которые содержат пробелы или символы новой строки или апострофы или обратной косой черты или двойные кавычки (и, возможно, имена файлов с байтами, которые не образуют действительных символов в локали).

 (export LC_ALL=C cd /mnt/dwh/ftp/dwh && ls -At1 | tail -n +21 | sed 's/"/\\"/g;s/.*/"&"/' | xargs rm -f -- ) 

исправить большинство из них, но у вас все еще будет проблема с именами файлов, содержащими символы новой строки. Проблема в том, что вывод ls -At1 не обрабатывается после обработки.

Вывод ls -Atd1 ./.* ./* может быть обработан после обработки (поскольку эти ./ префиксы указывают, где каждое имя файла начинается с вывода, но не легко), но вы рискуете достигнуть предела по числу аргументов, переданных команде, передавая список имен файлов таким образом.

Лучше всего было бы использовать оболочку, которая может выполнять эту сортировку в своих глоссах , или полагаться на расширения GNU, если вам нужно работать только с GNU-системами:

  cd /mnt/dwh/ftp/dwh && find . ! -name . -prune ! -type d -printf '%T@\t%p\0' | tr '\0\n' '\n\0' | sort -rn | tail -n +21 | cut -f 2- | tr '\0\n' '\n\0' | xargs -r0 rm -f 

Здесь мы исключаем файл типа directory , который будет влиять на нумерацию, но, вероятно, ближе к тому, что вы хотите, поскольку я не предполагаю, что вы хотите удалить каталоги. Если вы хотите удалить каталоги, удалите -type d и добавьте параметр -r в rm .

Или:

 eval "set -- $(COLUMNS=4294967295 ls -Atx --quoting-style=shell-always)" if [ "$#" -gt 20 ]; then shift 20 printf '%s\0' "$@" | xargs -r0 rm -f -- fi 

Или используйте общий язык программирования, такой как perl , python , ruby

  • цитаты внутри backticks внутри цитат в ksh
  • Unix-эпоха в миллисекундах
  • Как отсортировать файлы в Bash с помощью ddmmyy timestamps в имени
  • Измерение времени в ядре Linux: как связаны clock_gettime, gettimeofday и getrusage?
  • Bash: сортировка элементов массива по дате файла
  • find-cnewer сломан на NTFS-3g?
  • Время изменения Solaris 10
  • Преобразовать временную метку unix в hh: mm: ss: SSS (где SSS - миллисекунды) в AWK
  • Как использовать mogrify convert только в файлах с определенной датой создания?
  • Возможно ли обновлять измененные времена только без копирования файлов при использовании rsync?
  • Как изменить время BIRTH файла BSD (aka btime)?
  • Linux и Unix - лучшая ОС в мире.