Как я удаляю все файлы в каталоге с конкретными расширениями, за исключением последних 5 из них

Каталог содержит файлы с разными расширениями. Я хотел бы удалить все файлы с расширениями .gz, zx, ext4, за исключением последних 5 файлов. Я могу перечислить все эти файлы с помощью

ls -l | grep '\.gz\|xz\|ext4$' 

и я мог бы показать самые старые из них 5:

 ls -l | grep '\.gz\|xz\|ext4$' | head -5 

Или перечислите последние 5 файлов:

 ls -l | grep '\.gz\|xz\|ext4$' | tail -5 

Но я не знаю, как удалить все из них, кроме этих 5 файлов, перечисленных в приведенной выше команде.

5 Solutions collect form web for “Как я удаляю все файлы в каталоге с конкретными расширениями, за исключением последних 5 из них”

Если обычный порядок сортировки в порядке (т. Е. Ваши файлы названы по дате), а ваша оболочка поддерживает массивы, вы можете использовать их для этого, избегая обычных оговорок об использовании ls :

 F=(./*.{gz,xz,ext4}) # list files G=("${F[@]:5}") # pick all but the first five to another array G=("${F[@]:0:${#F[@]}-5}") # or pick all but the last five rm -- "${G[@]}" # remove them 

zsh может сортировать по дате в себе, поэтому это будет захватывать соответствующие файлы массиву, отсортированные по времени модификации

 F=(./*.(gz|xz|ext4)(Om)) 

( (Om) для последнего последнего, (om) для самого нового.) Обработайте массив, как указано выше.


Конечно, если вам нужно сортировать по дате изменения, нельзя использовать zsh и знать, что ваши имена файлов хороши , просто ls -t | tail -n +6 ls -t | tail -n +6 сделаю. ( tail -n +6 начинает печатать на шестой строке, то есть пропускает первую пятерку. Сначала у меня было по очереди).

С GNU ls, я думаю, мы могли бы попросить его указать имена файлов для создания подходящего ввода для оболочки, а затем заполнить массив выходным:

 eval "F=($(ls -t --quoting-style=shell-always ./*.{xz,gz}))" 

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

 ls -1 | grep '\.gz$\|xz$\|ext4$' | tail -n +6 | xargs rm 

Предостережения. В ваших файлах не должно быть пробелов / кавычек.

 set -f; set ./*.[gx]z ./*.ext4; [ "$#" -gt 5] && shift 5; rm -f "$@" 

Ниже будут работать любые типы имен файлов:

 td="`mktemp`" \ find . -maxdepth 1 -type f \( -name \*.[gx]z -o -name \*.ext4 \) -exec sh -c ' [ ! -s "$td" ] && [ "$#" -gt 5 ] && { shift 5; echo >> "$td"; } rm -f "$@" ' x {} + rm "$td" 

В bash:

ls -1 *.{gz,xz,ext4} | head -n-5 | xargs -r rm

Ключевым понятием является то, что head -n-5 будет печатать все строки, заканчивающиеся до 5-го с конца (т.е. все строки, кроме последних 5). Полагаю, вы понимаете все остальное.

Двойным для tail будет tail -n+6 который печатает все строки, начиная с 6-го (т.е. все строки, кроме первых 5).

Следующая команда перечисляет все, кроме последних 5 файлов:

 ls -l | grep '\.gz\|xz\|ext4$' | head -n `expr \`ls | grep '\.gz\|xz\|ext4$' | wc -l\` - 4` 

Вы должны иметь возможность конвертировать его в команду для простого удаления файлов.

Вы почти там.

Используйте длинный формат опций, чтобы указать количество требуемых строк, а затем отмените его. (Противоположная логика может использоваться с tail ).

head --lines=3 отпечатка с головы три строки

head --lines=-3 отпечатки с головы, за исключением последних трех

Вот пример использования head и восьмистрочного файла с именем f

 $ cat f line 1 line 2 line 3 line 4 line 5 line 6 line 7 line 8 $ head -3 f line 1 line 2 line 3 $ head --lines=3 f line 1 line 2 line 3 $ head --lines=-3 f line 1 line 2 line 3 line 4 line 5 

Убедитесь, что эта часть создает то, что вы хотите, прежде чем вы начнете удалять файлы.

Длинный вариант не является строго обязательным, но он не имеет права быть обратно совместимым с эволюцией хвостовых и головных команд, и мне легче запомнить.

head -n-3 эквивалентен длинному варианту head --lines=-3 f

Смотри ниже

 $ head -3 f #originally line 1 line 2 line 3 $ head -n3 f # line 1 line 2 line 3 $ head -n+3 f line 1 line 2 line 3 $ head -n-3 f line 1 line 2 line 3 line 4 line 5 $ 
  • В чем разница между результатами и эффективностью после добавления -f в rm и -print в поиске?
  • Предоставлять строки, хранящиеся в файле, в виде списка аргументов для команды?
  • Использовать xargs вместо псевдонимов
  • Что делает «-t» в команде mv? Пример ниже
  • Мне нужно "| xargs -n 1 ", чтобы обойти xargs -I побочный эффект?
  • Точный формат параметров xargs -I?
  • слишком длинная строка
  • правильное параллельное использование xargs
  • Как объединить входы xarg с большим количеством аргументов?
  • Найти, сочетание xargs и grep вызывает ошибку
  • Понимание -regex с GNU find
  • Interesting Posts
    Linux и Unix - лучшая ОС в мире.