Удалите все файлы, кроме новейшего скрипта 3 в bash
вопрос: Как удалить все файлы в каталоге, кроме новейшего 3?
найти новейшие 3 файла просто:
ls -t | head -3
но мне нужно найти все файлы, кроме новейших 3 файлов. Как это сделать и как удалить эти файлы в одной строке, не делая ненужный цикл for для этого?
для этого я использую скрипты Debian Wheezy и bash.
7 ответов
в этом списке будут перечислены все файлы, кроме новейших трех:
ls -t | tail -n +4
это удалит эти файлы:
ls -t | tail -n +4 | xargs rm --
это также будет список dotfiles:
ls -At | tail -n +4
и удалить с помощью dotfiles:
ls -At | tail -n +4 | xargs rm --
но будьте осторожны: парсинг ls
может быть опасно, когда имена файлов содержат забавные символы, такие как символы новой строки и пробелы. Если вы уверены, что ваши имена файлов не содержат забавных символов, то разбор ls
вполне безопасно, тем более, если это сценарий только один раз.
если вы разрабатываете сценарий для повторного использования, то вы, безусловно, не должны анализировать вывод ls
и используйте методы, описанные здесь:http://mywiki.wooledge.org/ParsingLs
следующее выглядит немного сложным, но очень осторожно, чтобы быть правильным, даже с необычными или намеренно злонамеренными именами файлов. К сожалению, для этого требуются инструменты GNU:
count=0
while IFS= read -r -d ' ' && IFS= read -r -d '' filename; do
(( ++count > 3 )) && printf '%s' "$filename"
done < <(find . -maxdepth 1 -type f -printf '%T@ %P' | sort -g -z) \
| xargs -0 rm -f --
объясняя, как это работает:
- найти излучает
<mtime> <filename><NUL>
для каждого файла в текущем каталоге. -
sort -g -z
выполняет общую (с плавающей запятой, а не целочисленную) числовую сортировку на основе первого столбца (раз) со строками, разделенными Нулс. - первый
read
наwhile
петля удаляет mtime (больше не требуется послеsort
делается). - второй
read
наwhile
цикл считывает имя файла (работает до нуля). - цикл увеличивает, а затем проверяет счетчик; если состояние счетчика указывает, что мы прошли начальный пропуск, то мы печатаем имя файла, разделенное нулем.
-
xargs -0
затем добавляет Это имя файла в список argv это сбор для вызоваrm
С.
это сочетание ceving и ответ Анубхава по.
Оба решения не работают для меня. Поскольку я искал скрипт, который должен запускаться каждый день для резервного копирования файлов в архиве, я хотел избежать проблем с ls
(кто-то мог сохранить какой-то забавный файл имени в моей папке резервного копирования). Поэтому я изменил упомянутые решения в соответствии со своими потребностями.
Soltution Ceving это удаляет три новые файлы - не то, что мне нужно и спросил.
мое решение удаляет все файлы за исключением три новых файла.
find . -type f -printf '%T@\t%p\n' |
sort -t $'\t' -g |
head -n -3 |
cut -d $'\t' -f 2- |
xargs rm
объяснение:
find
выводит список всех файлов (не каталогов) в текущей папке. Они распечатаны с временными метками.sort
сортирует строки на основе типа timestamp (старые сверху).head
выводит верхние строки, вплоть до последних 3 строк.cut
удаляет метки.xargs
работает rm
для каждого выбранного файла.
для вас проверьте мое решение:
(
touch -d "6 days ago" test_6_days_old
touch -d "7 days ago" test_7_days_old
touch -d "8 days ago" test_8_days_old
touch -d "9 days ago" test_9_days_old
touch -d "10 days ago" test_10_days_old
)
это создает 5 файлов с различными метками времени в текущей папке. Сначала запустите это и код для удаления, чтобы проверить код.
не используйте ls -t
поскольку небезопасно для имен файлов, которые могут содержать пробелы или специальные символы glob.
вы можете сделать это, используя все gnu
на основе утилиты для удаления всех, кроме 3 новейших файлов в текущем каталоге:
find . -maxdepth 1 -type f -printf '%T@\t%p' |
sort -z -nrk1 |
tail -z -n +4 |
cut -z -f2- |
xargs -0 rm -f --
в zsh:
rm /files/to/delete/*(Om[1,-4])
если вы хотите включить dotfiles, заменить часть в скобках на (Om[1,-4]D)
.
Я думаю, что это правильно работает с произвольными символами в именах файлов (только что проверено с новой строкой).
пояснение: скобки содержат квалификаторы Glob. O
означает "порядок, по убыванию", m
означает mtime (см. man zshexpn
для других ключей сортировки-большой manpage; поиск "быть отсортированы"). [1,-4]
возвращает только играм по индексу 1 (последний + 1 - 4) (Примечание -4
для удаления всех, кроме 3).
использует find
вместо ls
С преобразование Шварца.
find . -type f -printf '%T@\t%p\n' |
sort -t $'\t' -g |
tail -3 |
cut -d $'\t' -f 2-
find
поиск файлов и украшает их штамп времени и использует табулятор для разделения двух значений. sort
разбивает входные данные табулятором и выполняет общую числовую сортировку, которая сортирует числа с плавающей запятой правильно. tail
должно быть очевидно и cut
undecorates.
проблема с украшениями вообще найти соответствующее разделитель, который не является частью входных данных, имен файлов. Это ответ использует символ NULL.