Jak usunąć wszystkie pliki w folderze oprócz niektórych określonych plików?

11

Chcę usunąć wszystkie pliki z katalogu, pozostawiając tylko niektóre określone pliki, nie mają one nic wspólnego według nazwy. Jak mogłem to osiągnąć?

Na przykład nazwy plików, które chcę zachować, to:

file_1.png, another_file.jpg,some_music.mp3

AGamePlayer
źródło

Odpowiedzi:

15

Jeśli używasz bash:

shopt -s extglob
rm -- !(file1|file2|file3)

Pierwszy wiersz aktywuje tylko rozszerzone dopasowanie wzorca, a następnie używamy jednego z nich:

!(pattern-list) dopasowuje cokolwiek oprócz jednego z podanych wzorów

a lista wzorów jest listą jednego lub więcej wzorów oddzielonych znakiem |.


Lub z zsh

setopt extendedglob
rm -- ^(file1|file2)

Lub bardziej przenośny, używając find:

find . -maxdepth 1 ! -name 'file1' ! -name 'file2' -type f -exec rm -v {} +
jimmij
źródło
3
Przydatne może być uwzględnienie sposobu zwracania opcjonalnego zachowania powłoki back ( shopt -u extglob).
geedoubleya
7

Utwórz podkatalog tmp, przenieś wszystkie pliki, które chcesz zachować, do tego katalogu, a rm -f *następnie wykonaj później. Nie wpłynie to na tmpkatalog.

Następnie po prostu wykonaj:

mv tmp/* .
rmdir tmp

(Zakładając, że żaden z przeniesionych plików nie zaczyna się od kropki).

Jest to jeden z niewielu przypadków, w których sensowne jest używanie myszy i przeglądarki plików, takich jak Nautilus, w których można faktycznie Ctrl-kliknąć kilka plików, które chcesz zachować, a następnie użyć menu: Edit -> Invert Selectionaby pobrać inne pliki, a następnie usunąć je .

Anthon
źródło
przenoszenie plików do katalogu tmp brzmi nieźle. W każdym razie muszę to zrobić za pomocą wiersza polecenia. Dzięki!
AGamePlayer
3
@AwQiruiGuo Tmp ma tę zaletę, że najpierw dzieli pliki na dwa zestawy, a następnie nieodwracalnie usuwa te, których nie chcesz. Możesz więc uruchomić i lssprawdzić, czy nie przegapiłeś żadnego z plików, które chcesz zachować.
Anthon
2

Dodaj nazwy plików, które chcesz zachować, do pliku tekstowego, po jednym w wierszu. Ten plik nie powinien znajdować się w katalogu lub należy również dodać jego nazwę.

Jeśli nazwa twojego katalogu to foo, a nazwa pliku to bar , wykonaj następujące czynności.

find foo -type f -print0|grep -vzZ -f bar|xargs -0 rm

Robi to:

  1. find -type fwyszukuje nazwy wszystkich plików w foo i jego podkatalogach i drukuje je do STDOUT. Z opcją -print0to ogranicza nazwy plików z NUL bajtów.
  2. grep -v -f barwyklucza wszystkie nazwy plików pasujące do linii na pasku . Z opcją -ztraktuje dane wejściowe jako zbiór linii ograniczonych bajtem NUL, z opcją -Zogranicza dane wyjściowe bajtem NUL.
  3. xargs rmwywołuje rmwielokrotnie, aby usunąć pliki. Z opcją -0traktuje dane wejściowe jako zbiór linii ograniczonych bajtem NUL.

Działa to z nazwami plików zawierającymi białe znaki.

Mathias Weidner
źródło
To nie zadziała, ponieważ nazwy plików mogą mieć w sobie nowe linie.
Anthon
@Anthon zmienił opcje find, grep, xargs, aby radzić sobie z nazwami plików zawierającymi białe znaki, w tym znak nowej linii
Mathias Weidner
Jeśli chcesz użyć find, wolałbymfind . -maxdepth 1 ! -name 'file1' ! -name 'file2' -type f -exec rm -vi {} +
jimmij