Як видалити всі файли, окрім шаблону * .txt?


73

Я знаю, як видалити весь txtфайл у поточному каталозі rm *.txt. Хтось знає, як видалити всі файли в поточному txtфайлі EXCEPT ?


20
Як завжди, перевіряйте дані відповіді нешкідливою командою, як і lsраніше, ніж насправді намагалися зателефонувати rm.
чепнер

Відповіді:


111

Ви можете використовувати find:

find . -type f ! -name '*.txt' -delete

Або розширені можливості глобуса:

shopt -s extglob
rm *.!(txt)

Або в zsh:

setopt extendedglob
rm *~*.txt(.)
#  ||     ^^^ Only plain files
#  ||^^^^^ files ending in ".txt"
#  | \Except
#   \Everything

Деякі з них можуть знадобитися адаптувати залежно від того, чи є у вас папки та що ви хочете робити з ними.
Кевін

1
Не повинно *.!(txt)бути !(*.txt)?
Лрі

@LauriRanta залежить від того, що в папці, на що ми не отримали відповіді. Це добре, як якщо б усі файли мають розширення, і rmзадушиться, якби були папки.
Кевін

У мене проблема з дужками. Коли я використовую стиль глобуса в скрипті bash, він скаржиться на синтаксичну помилку та круглі дужки. Однак це працює з CLI працює.
CMCDragonkai

1
@izogfif перевірити це find . -type f ! -name "*.txt" | xargs -r rmбуде працювати в GNU \ xargs. Команди BSD і UNIX xargs можуть не мати -ж вам доведеться перевірити свій місцевийman xargs
Ntwobike

10

Якщо ви просто хочете видалити всі файли, окрім "* .txt", тоді ви можете скористатися такою командою:

$ find . -type f ! -name "*.txt" -exec rm -rf {} \;

але якщо ви також хочете видалити каталоги разом з файлами, ви можете скористатися цим:

$ find . ! -name "*.txt" -exec rm -r {} \;


9

Є багато способів зробити це. але найпростішим способом було б (удар):

shopt -s extglob
rm !(*.txt)

4

Одне рішення без find:

mv dir/*.txt otherdir/
rm -r dir
mv otherdir dir

Це повинно працювати на всіх видах снарядів.


3

Можна використовувати перевернутий греп і xargs

ls | grep -v .txt$| xargs rm

ls | grep -v *.txt | xargs rmпрацює так само добре
phillipsk

@phillipsk grep -v *.txtпрацюватиме лише за наявності лише одного .txtфайлу. Якщо цього немає, grepвикористовуватимемо *.txtяк шаблон; якщо є більше одного, він буде шукати перше ім'я файлу у всіх інших .txtфайлах, ігноруючи вихід з ls. (Точні результати можуть залежати від
глобальних

.txt$буде відповідати рядкам, що закінчуються txtнезалежно від крапки. Тому що grepприймає регулярний вираз як параметр. Отже, файли a.txtі aatxtі a-txtвсі будуть відповідати цьому виразу. Правильний вираз повинен бути ls | grep -v \\.txt$ | xargs --no-run-if-empty rm. Для допитливих людей: Якщо ви хочете пограти з виразом, сміливо використовуйте цей тестовий вираз ls | grep \\.txt$ | xargs --no-run-if-empty echo(зверніть увагу: немає -vпрапора і rm=>echo). Примітка2: ви, можливо, помітили подвійний нахил. Один призначений для регулярного вираження, інший - для того, щоб уникнути риси.
Димитрій К

1

Просто робіть:

rm $(ls -I "*.txt" ) # Видає тип файлу, крім * .txt

Так само, якщо потрібно видалити "крім одного або декількох типів файлів", зробіть:

rm $(ls -I "*.txt" -I "*.pdf" ) # Видає типи файлів, крім * .txt & * .pdf


Ласкаво просимо до StackExchange! -IВаріант може бути корисний, але бачити , чому не розібрати Ls . І що | xargsдосягає? Без жодних аргументів він просто працює echoна всіх своїх вкладах.
JigglyNaga

Чого xargsслід досягти?
даг

Дякую, xargs не був корисним у наведеному вище випадку, виправили зараз.
Сурія

0

Це також працює для видалення всіх прихованих (крапкових) файлів і папок, крім вказаного ( .mydir):

rm -rf $(ls -aI ".mydir")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.