Jak usunąć wszystkie pliki w katalogu oprócz niektórych?
123
Muszę usunąć wszystkie pliki z katalogu, ale wykluczyć niektóre z nich. Na przykład w katalogu z plikami a b c ... zmuszę usunąć wszystkie oprócz ui p. Czy jest na to łatwy sposób?
Poniższe odpowiedzi są o wiele lepsze, ale możesz po prostu sprawić, by pliki zapisywały tylko do odczytu, usuwały wszystkie, a następnie przywracały je do pierwotnych uprawnień (o ile nie używasz rm -f). Musisz wiedzieć, jakie uprawnienia przywrócić, i musisz wiedzieć, że podczas procesu nic nie wymagało dostępu do zapisu. Dlatego inne odpowiedzi są lepsze.
Joe
1
Jeśli chcesz również usunąć ukryte pliki, uruchom shopt -s dotglobprzed uruchomieniem rm (...).
Odpowiedzi:
108
W tych przypadkach piszę
rm *
Następnie naciskam Ctrl+ X, *aby rozwinąć* do wszystkich widocznych nazw plików.
Następnie mogę po prostu usunąć z listy dwa pliki, które chcę zachować, i na koniec uruchomić wiersz poleceń.
musisz mieć aktywną funkcję „extglobbing”: shopt -s extglob
sparkie
18
Musisz shopt -s extglob, @Ashot. Poza tym to tylko pliki, a nie katalogi, dlatego usunąłem -rfopcje z twojego polecenia.
slhck
3
Jeśli trzeba wykluczyć jeden plik z wyborem plików, spróbuj tego: rm !(index).html. Spowoduje to usunięcie wszystkich plików z rozszerzeniem „.html”, z wyjątkiem „index.html”.
mzuther
71
Możesz użyć find
find .!-name u !-name p -maxdepth 1-type f -delete
! neguje następne wyrażenie
-name określa nazwę pliku
-maxdepth 1spowoduje, że find przetworzy tylko podany katalog ( finddomyślnie katalogi przechodzą)
-type f będzie przetwarzać tylko pliki (a nie na przykład katalogi)
-delete usunie pliki
Następnie możesz dostroić warunki, patrząc na stronę podręcznika wyszukiwania
Aktualizacja
Należy pamiętać, że kolejność elementów wyrażeń jest znacząca (patrz dokumentacja)
Przetestuj najpierw swoje polecenie, używając -printzamiast-delete
Offcourse, mv je do katalogu wyżej. Staraj się nie przenosić ich do podkatalogu, który usuwasz ...
Konerak
@Konerak: rmbez -rnie usunie podkatalogów.
reinierpost
11
Spowoduje to zastąpienie plików o tej samej nazwie w katalogu docelowym
Matteo
7
Głosuję za tym, ponieważ chociaż może być przydatny, jest także nieatomowy i skutecznie usuwa wszystkie pliki z katalogu w krótkim okresie czasu; byłoby to nie do przyjęcia, jeśli na przykład pliki są udostępniane w sieci.
sam hocevar
15
Trochę podobne do tej odpowiedzi, ale nie są potrzebne żadne specjalne opcje, o ile wiem, że „starożytna” funkcjonalność jest obsługiwana przez dowolną (niejasno) / bin / sh przypominającą powłokę (np. Bash, zsh, ksh itp.)
Działa to dla nazw plików 1-znakowych. W przypadku dłuższych nazw odpowiedź sparkie jest lepsza.
glenn jackman
3
Co byłoby nie tak rm [^up]*? Często robię podobne rzeczy.
CVn
3
@ MichaelKjörling - spowoduje to usunięcie wszystkich plików zaczynających się od u lub p, nie tylko tych o nazwach u i p. Myślę, że OP (@Ashot) oznaczało az i u, p itd. symbolicznie i nie dosłownie.
Sudipta Chatterjee
4
@HobbesofCalvin To usunie wszystkie pliki, które nie zaczynają się od u lub p, a nie te, które zaczynają się od nich.
rjmunro
@rjmunro - dzięki, przegapiłem ten! :)
Sudipta Chatterjee
11
Robiąc to bez znalezienia:
ls | grep -v '(u|p)'| xargs rm
(Edycja: „u” i „v”, podobnie jak w innych miejscach tutaj, są używane jako ogólne wersje całych wyrażeń regularnych. Oczywiście musisz zachować ostrożność, aby zakotwiczyć wyrażenia regularne, aby uniknąć dopasowania zbyt wielu rzeczy.)
Zdecydowanie będziesz potrzebować skryptu, jeśli będziesz robić dużo z tego, jak sugerowali inni.
grep domyślnie nie obsługuje rozszerzonego wyrażenia regularnego: użyj -Ealboegrep
Matteo
2
będzie to wykluczyć plik zawierający ulubp
Matteo
@Matteo Nie, nie będzie. Grep nie grepuje plików, to grepuje wyjście polecenia ls. Zastanawiasz się nad tym, grep -L (u|p)' * | xargs rmgdzie -Loznacza, że nazwy plików list nie zawierają dopasowania.
rjmunro
4
Och, masz na myśli każdy plik, którego nazwa zawiera ulub pżaden plik zawierający a ulub a p. To jest poprawne. Możesz to naprawić za pomocąegrep -v '^(u|p)$'
rjmunro,
1
Tutaj usuwa się wszystko oprócz tych dopasowań! ls | grep -v 'vuze\|progs' | xargs rm -rf
Nick
6
W Zsh:
setopt extended_glob # probably in your .zshrc
następnie
rm ^(u|p)
lub
rm *~(u|p)
Drugi będzie działać nawet jeśli masz ^w $histcharsHistorii substytucji, i oczywiście można umieścić dowolną glob przed ~.
To nie działa na mojej powłoce (GNU bash 4.1.5 (1)). Najpierw przetestuj go z czymś nieco mniej szkodliwym niżrm w katalogu testowym!
CVn
3
W erze dyskietek miałem plik wykonywalny dos o nazwie „Z wyjątkiem”, który tymczasowo przenosiłby rzeczy z bieżącego katalogu i wykonywał polecenie, aby można było powiedzieć:
oprócz * .txt del *. *
aby usunąć wszystko oprócz plików tekstowych.
Byłoby to dość trywialne zaimplementowanie jako skrypt powłoki, a jeśli jest to coś, co możesz zrobić więcej niż dwa razy, wydaje się, że byłby to dobry pomysł.
Dla tych, którzy wolą określać dowolne złożone wzorce wykluczania (obejmujące wszystkie zmienione nazwy plików) w pełnym stylu emacs wyrażenia regularnego, posix-awk lub rozszerzonym posix-em (zobacz stronę man) polecam ten. W tym przykładzie wyklucza uiw pobecnym reż. Może to być przydatne w przypadku skryptów.
Musisz podać katalog przed wyrażeniem (`find. -Regextype ...).
Matteo,
-regextypebędzie działać tylko na wersjach GNU
Matteo
no - moja wersja find (ściśnięcie Debiana) definitywnie nie wymaga jawnego katalogu przed wyrażeniem, jeśli należy użyć bieżącego katalogu
sparkie
@sparke: działa to tylko w przypadku implementacji GNU
Matteo
@sparkie: brak zdefiniowania katalogu (pierwszego parametru) findjest rozszerzeniem findpolecenia GNU . To samo dotyczy -regextypeopcji. Ponadto twoje polecenie usunie również pliki z podkatalogów, podczas gdy pierwotne pytanie wyraźnie zadawało pytania dotyczące plików w katalogu.
Mikko Rantalainen,
1
Zawsze używam:
rm [a-o,q-t,v-z]*
Umożliwi to określenie stopnia szczegółowości. Jeśli więc chcesz usunąć pliki od O do Z, możesz użyć:
shopt -s dotglob
przed uruchomieniemrm (...)
.Odpowiedzi:
W tych przypadkach piszę
Następnie naciskam Ctrl+ X, *aby rozwinąć
*
do wszystkich widocznych nazw plików.Następnie mogę po prostu usunąć z listy dwa pliki, które chcę zachować, i na koniec uruchomić wiersz poleceń.
źródło
*
rozwija, nie jest zbyt długa. : -}Ctrl
+Shift
+x
+*
Do
rm
wszystkich opróczu,p
bash wystarczy wpisać:Wymaga to ustawienia następującej opcji:
Zobacz więcej: glob - Wiki Grega
źródło
shopt -s extglob
, @Ashot. Poza tym to tylko pliki, a nie katalogi, dlatego usunąłem-rf
opcje z twojego polecenia.rm !(index).html
. Spowoduje to usunięcie wszystkich plików z rozszerzeniem „.html”, z wyjątkiem „index.html”.Możesz użyć
find
!
neguje następne wyrażenie-name
określa nazwę pliku-maxdepth 1
spowoduje, że find przetworzy tylko podany katalog (find
domyślnie katalogi przechodzą)-type f
będzie przetwarzać tylko pliki (a nie na przykład katalogi)-delete
usunie plikiNastępnie możesz dostroić warunki, patrząc na stronę podręcznika wyszukiwania
Aktualizacja
Przetestuj najpierw swoje polecenie, używając
-print
zamiast-delete
źródło
-delete
zaraz po.
nim będzie katastrofą (usunie wszystkie pliki w CWD)find . -maxdepth 1 -type f -name '[^up]' -delete
find
jest moim najlepszym przyjacielem, zwłaszcza gdy jest zbyt wiele plików do globProsty:
mv
pliki, które chcesz w górnym katalogu,rm
w katalogu, a następnie zmv
powrotem.źródło
rm
bez-r
nie usunie podkatalogów.Trochę podobne do tej odpowiedzi, ale nie są potrzebne żadne specjalne opcje, o ile wiem, że „starożytna” funkcjonalność jest obsługiwana przez dowolną (niejasno) / bin / sh przypominającą powłokę (np. Bash, zsh, ksh itp.)
źródło
rm [^up]*
? Często robię podobne rzeczy.Robiąc to bez znalezienia:
(Edycja: „u” i „v”, podobnie jak w innych miejscach tutaj, są używane jako ogólne wersje całych wyrażeń regularnych. Oczywiście musisz zachować ostrożność, aby zakotwiczyć wyrażenia regularne, aby uniknąć dopasowania zbyt wielu rzeczy.)
Zdecydowanie będziesz potrzebować skryptu, jeśli będziesz robić dużo z tego, jak sugerowali inni.
źródło
-E
alboegrep
u
lubp
grep -L (u|p)' * | xargs rm
gdzie-L
oznacza, że nazwy plików list nie zawierają dopasowania.u
lubp
żaden plik zawierający au
lub ap
. To jest poprawne. Możesz to naprawić za pomocąegrep -v '^(u|p)$'
ls | grep -v 'vuze\|progs' | xargs rm -rf
W Zsh:
następnie
lub
Drugi będzie działać nawet jeśli masz
^
w$histchars
Historii substytucji, i oczywiście można umieścić dowolną glob przed~
.źródło
GLOBIGNORE przyjmuje listę rozdzieloną dwukropkami
źródło
rm
w katalogu testowym!W erze dyskietek miałem plik wykonywalny dos o nazwie „Z wyjątkiem”, który tymczasowo przenosiłby rzeczy z bieżącego katalogu i wykonywał polecenie, aby można było powiedzieć:
aby usunąć wszystko oprócz plików tekstowych.
Byłoby to dość trywialne zaimplementowanie jako skrypt powłoki, a jeśli jest to coś, co możesz zrobić więcej niż dwa razy, wydaje się, że byłby to dobry pomysł.
źródło
Spowoduje to usunięcie wszystkich plików oprócz u i p w unixie
źródło
Dla tych, którzy wolą określać dowolne złożone wzorce wykluczania (obejmujące wszystkie zmienione nazwy plików) w pełnym stylu emacs wyrażenia regularnego, posix-awk lub rozszerzonym posix-em (zobacz stronę man) polecam ten. W tym przykładzie wyklucza
u
iwp
obecnym reż. Może to być przydatne w przypadku skryptów.źródło
-regextype
będzie działać tylko na wersjach GNUfind
jest rozszerzeniemfind
polecenia GNU . To samo dotyczy-regextype
opcji. Ponadto twoje polecenie usunie również pliki z podkatalogów, podczas gdy pierwotne pytanie wyraźnie zadawało pytania dotyczące plików w katalogu.Zawsze używam:
Umożliwi to określenie stopnia szczegółowości. Jeśli więc chcesz usunąć pliki od O do Z, możesz użyć:
źródło
Jeszcze inna wersja wykorzystująca
xargs
:Należy pamiętać, że
xargs -I
jest to potrzebne do poprawnego obsługiwania nazw plików, w tym spacji.źródło
Jeszcze inny:
Jest to dość długie i nie wiem, czy można łatwo przekształcić go w funkcję, która z łatwością pomieści dowolną liczbę argumentów, ale działa dobrze.
I to czysta dobroć.
źródło
Oto inny wariant. Możesz pisać:
lub:
Więc
rm
poprosi, aby potwierdzić usunięcie każdego pliku.źródło
Posługiwać się:
w celu usunięcia wszystkich plików, w tym katalogów, z wyjątkiem plików u, p i .ext.
źródło
Prosty sposób, który trudno zepsuć: powiedzmy, że chcesz usunąć wszystko oprócz * .pdf:
źródło