Виключіть один зразок із глобальної відповідності


53

У мене є кілька файлів з однаковим базовим файлом. Я хотів би видалити всі, крім одного

foo.org #keep
foo.tex #delete
foo.fls #delete
foo.bib #delete
etc

Якщо мені не потрібно було зберігати його, я знаю, що міг би скористатися rm foo.*.

TLDP демонструє ^заперечення матчу. Через спроби та помилки я зміг це знайти

rm foo.*[^org]

робить те, що мені потрібно, але я не дуже розумію синтаксис.

Крім того, хоча це не обмеження в моєму випадку використання, я думаю, що ця модель також ігнорує foo.oі foo.or. Як працює ця модель і як виглядатиме лише глобус, який ігнорує foo.org?


1
Як додаток до відповіді @glen, варто згадати, що rm foo.*[^org]видаляються всі файли, останнім символом яких є ні o, rабо g, так foo.fooби не відповідало жодному.
jimmij

Ви використовуєте Regular Expression. Вам слід бути обережними з групуючими персонажами. Використовуючи дужки, ви вказали клас символів, що означає, що ви можете видалити будь-які файли, що мають розширення з літерами o, rабо gв будь-якому порядку. Використовуйте дужки для створення групи та збереження порядку символів.
Містер Маскаро

3
@ jbarker2160 - це насправді не регулярний вираз, його частіше називають глобусом (або шаблоном імені файлу ), який є більш-менш підмножиною регулярного виразу - детальніше див. Його шаблон foo.*[^org]буде відповідати будь-якому імені файлу, яке починається з foo.одного або декількох символів після крапки, де останній символ не є o, r або g. Так що це буде відповідати foo.orb, але не foo.orgабо foo.orабо foo.o. Відповідь GlennJackman показує, як увімкнути розширені функції узгодження шаблону, щоб відмінити відповідність.
Джонні

Відповіді:


52
shopt -s extglob
echo rm foo.!(org)

Це "foo". після чого нічого НЕ "org"

посилання: https://www.gnu.org/software/bash/manual/bashref.html#Pattern-Matching


Я намагався робити те саме, але з дужками, і, мабуть, при використанні дужок це не працює
Donato

4
Який синтаксис відповідає декільком іменам файлів? скажіть, я хочу виключити .org, .png, .txt?
Фредо

@Freedo @()для модельну списку: stackoverflow.com/a/217208/3779853
phil294

23

В bash ви також можете використовувати GLOBIGNORE="*.org"; rm -i foo*.

А unset GLOBIGNOREколи закінчиться.

Це насправді не краще shopt -s extglob, але мені легше запам'ятати.


5
@Ruslan Це не працює. Ви повинні зробити( GLOBIGNORE="*.org"; rm -i foo* )
DBedrenko

3
Зверніть увагу, якщо ви хочете розширити список ігнорованих, розділіть їх двокрапкою, наприкладGLOBIGNORE="*foo*:*bar*"
фіат

7

Труба може зробити?

ls * | grep -v "foo.org" | xargs -I {} echo {}

(очевидно, ви можете замінити ехо на rm в останньому ланцюжку).


Корисно, якщо потрібно лише в одному рядку.
bruceskyaus

1
Простіше запам’ятати (для мене я роблю подібні речі часто) і дозволяє більш складну обробку для завантаження :)
drevicko

1
ls -1повинні бути надійнішими, щоб забезпечити grep
обробку

0

ОП було дуже близько:

rm foo.*[^o][^r][^g]

хоча в цьому випадку *це зайве.

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