![Удалить все файлы, кроме файлов с расширением pdf в каталоге](https://rvso.com/image/977075/%D0%A3%D0%B4%D0%B0%D0%BB%D0%B8%D1%82%D1%8C%20%D0%B2%D1%81%D0%B5%20%D1%84%D0%B0%D0%B9%D0%BB%D1%8B%2C%20%D0%BA%D1%80%D0%BE%D0%BC%D0%B5%20%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2%20%D1%81%20%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC%20pdf%20%D0%B2%20%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3%D0%B5.png)
У меня есть каталог, содержащий следующее:
x.pdf
y.zip
z.mp3
a.pdf
Я хочу удалить все файлы, кроме x.pdf
и a.pdf
. Как это сделать из терминала? Подкаталогов нет, поэтому нет необходимости в рекурсии.
решение1
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
- Первая команда перенесет вас в каталог, в котором вы хотите удалить файлы.
- Вторая команда удалит все файлы, кроме тех,
.pdf
имя которых заканчивается на
Например, если temp
в вашей домашней папке есть каталог с именем:
cd ~/temp
затем удалите файлы:
find . -type f ! -iname "*.pdf" -delete
Это приведет к удалению всех файлов, кроме xyz.pdf
.
Вы можете объединить эти две команды, чтобы:
find ~/temp -type f ! -iname "*.pdf" -delete
.
текущий каталог. !
означает выбрать все файлы, кроме тех, которые находятся .pdf
в конце. -type f
выбирает только файлы, а не каталоги. -delete
означает удалить его.
ПРИМЕЧАНИЕ: эта команда удалит все файлы (кроме файлов PDF, но включая скрытые файлы) в текущем каталоге, а также во всех подкаталогах. !
должен стоять перед -name
. просто -name
включит только .pdf
, в то время как -iname
включит .pdf
и.PDF
Чтобы удалить только текущий каталог, но не подкаталоги, добавьте -maxdepth 1
:
find . -maxdepth 1 -type f ! -iname "*.pdf" -delete
решение2
С помощью bash
расширенной подстановки оболочки вы можете удалить любые файлы с расширениями, отличными от .pdf
используемых
rm -- *.!(pdf)
Как отметил @pts, --
символы обозначают конец любых параметров команды, что делает команду безопасной в редких случаях, когда имена файлов начинаются с -
символа.
Если вы хотите удалить файлы без расширения, а также файлы с расширениями, отличными от .pdf
, то, как указал @DennisWilliamson, вы можете использовать
rm -- !(*.pdf)
Расширенная подстановка должна быть включена по умолчанию, но если нет, вы можете сделать это с помощью
shopt -s extglob
Особенно если вы собираетесь использовать это внутри скрипта, важно отметить, что если выражение ничему не соответствует (т. е. если в каталоге нет файлов, отличных от PDF), то по умолчанию глоб будет передан команде неразвернутым rm
, что приведет к ошибке типа
rm: cannot remove `*.!(pdf)': No such file or directory
Вы можете изменить это поведение по умолчанию с помощью nullglob
опции shell, однако это имеет свою собственную проблему. Для более подробного обсуждения см.NullGlob - Вики Грега
решение3
$ cd <the directory you want>
$ gvfs-trash !(*.pdf)
Или с помощью mv
команды (но таким образом вы не сможете восстановить его из корзины, так как он не записывает информацию .trashinfo, так что это означает, что вы переместили свои файлы вместо назначениягде это выглядит следующим образом).
mv !(*.pdf) ~/.local/share/Trash/files
решение4
Используйте GLOBIGNORE из bash:
GLOBIGNORE=x.pdf:a.pdf
rm *
unset GLOBIGNORE
Из страницы руководства bash:
ГЛОБИГНОРЕ: Список шаблонов, определяющих набор, разделенных двоеточиями имен файлов, которые следует игнорировать при расширении имени пути.
Быстрый тест:
mkdir /tmp/foooooo
cd /tmp/foooooo
touch x.pdf y.zip z.mp3 a.pdf
GLOBIGNORE=x.pdf:a.pdf
ls -1 *
Выход:
y.zip z.mp3