2013-01-08 12:17:05 +0000 2013-01-08 12:17:05 +0000
123
123

Jak usunąć wszystkie pliki w katalogu z wyjątkiem niektórych?

Muszę usunąć wszystkie pliki w katalogu, ale wykluczyć niektóre z nich. Na przykład, w katalogu z plikami a b c ... z, muszę usunąć wszystkie z wyjątkiem u i p. Czy istnieje łatwy sposób, aby to zrobić?

Odpowiedzi (17)

144
144
144
2013-01-08 12:34:49 +0000

Aby rm wszystkie oprócz u,p w bashu wystarczy wpisać:

rm !(u|p)

Wymaga to ustawienia następującej opcji:

shopt -s extglob

Zobacz więcej: glob - Greg’s Wiki

108
108
108
2013-01-08 12:18:23 +0000

Co robię w takich przypadkach, to wpisuję

rm *

Następnie naciskam Ctrl+X, aby rozszerzyć * na wszystkie widoczne nazwy plików.

Następnie mogę po prostu usunąć dwa pliki, które chcę zachować z listy i ostatecznie wykonać wiersz poleceń.

71
71
71
2013-01-08 12:35:05 +0000

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 1 sprawi, że find przetworzy tylko podany katalog (find domyślnie przemierza katalogi)
  • -type f przetworzy tylko pliki (a nie np. katalogi)

- -delete usunie pliki

. -print usunie pliki

Możesz następnie dostroić warunki patrząc na man page of find

Update

  • Pamiętaj, że kolejność elementów wyrażeń jest istotna (zobacz dokumentację)
  • Przetestuj swoje polecenie najpierw używając -delete zamiast 0x6&
43
43
43
2013-01-08 12:22:58 +0000

Proste:

mv pliki, które chcesz w górnym katalogu, rm katalog, a następnie mv je z powrotem.

15
15
15
2013-01-08 14:22:21 +0000

Nieco podobne do ta odpowiedź , ale nie są potrzebne żadne specjalne opcje, o ile wiem, poniższe jest “starożytną” funkcjonalnością obsługiwaną przez każdą (w przybliżeniu) powłokę przypominającą /bin/sh (np. bash, zsh, ksh, etc)

rm [^up]
11
11
11
2013-01-09 03:54:14 +0000

Robiąc to bez find:

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 regexów. Oczywiście będziesz chciał być ostrożny, aby zakotwiczyć swoje regexy, aby uniknąć dopasowania zbyt wielu rzeczy).

Zdecydowanie będziesz chciał mieć skrypt, jeśli zamierzasz robić dużo z tego, jak sugerowali inni.

6
6
6
2013-01-09 22:34:13 +0000

W zsh:

setopt extended_glob # probably in your .zshrc

następnie

rm ^(u|p)

lub

rm *~(u|p)

To drugie zadziała nawet jeśli masz ^ w $histchars do podstawiania historii, i oczywiście możesz umieścić dowolny glob przed ~.

5
5
5
2013-01-08 16:32:06 +0000

GLOBIGNORE pobiera listę rozdzieloną dwukropkami

GLOBIGNORE=u:p
rm *
3
3
3
2013-01-08 17:58:46 +0000
find . -maxdepth 1 ! -name "u" ! -name "p" -type f -exec rm -rf {} \;

Spowoduje to usunięcie wszystkich plików oprócz u i p w unixie

3
3
3
2013-01-08 17:02:15 +0000

Jeszcze w erze dyskietek miałem dosowy program wykonywalny o nazwie “Except”, który tymczasowo przenosił rzeczy z bieżącego katalogu i wykonywał polecenie, więc mogłeś powiedzieć:

except \*.txt del \*.\*

aby usunąć wszystko oprócz twoich plików tekstowych.

Byłaby to dość trywialna rzecz do zaimplementowania jako skrypt powłoki i jeśli jest to rodzaj rzeczy, którą prawdopodobnie zrobisz więcej niż dwa razy, wydaje się, że byłby to dobry pomysł.

2
2
2
2013-01-08 18:16:45 +0000

Dla tych, którzy wolą podawać dowolnie złożone wzorce wykluczeń (obejmujące wszystkie nazwy plików) w pełnym stylu regexp emacs, posix-awk lub posix-extended (zobacz stronę man find) polecam ten. Wyklucza on u i p w bieżącym dir w tym przykładzie. Może to być przydatne dla skryptów.

find -regextype posix-awk ! -regex './(u|p)' -print0 | xargs -0 rm -rf
1
1
1
2014-09-24 03:05:26 +0000

Jeszcze inny:

for FILE in ./*; do if [[$FILE != ./u*]] || [[$FILE != ./p*]];then rm $FILE; fi; done;

Jest to rodzaj długiego i nie wiem, czy można łatwo zrobić z niego funkcję, która mogłaby łatwo pomieścić i arbitralną liczbę argumentów, ale działa dobrze.

I jest to czysta bashowa dobroć.

1
1
1
2014-10-22 12:37:57 +0000

Oto inny wariant. Można wpisać:

rm -i *

lub:

rm --interactive *

Czyli rm poprosi Cię o potwierdzenie usunięcia każdego pliku.

1
1
1
2016-09-11 02:33:03 +0000

Użyj:

find . -type f ! -name 'u' ! -name 'p' ! -name '*.ext' -delete
find . -type d ! -name 'u' ! -name 'p' ! -name '*.ext' -delete

w celu usunięcia wszystkich plików, w tym katalogów, z wyjątkiem plików u, p i .ext.

1
1
1
2013-01-09 20:54:59 +0000

Ja zawsze używam:

rm [a-o,q-t,v-z]*

To pozwoli ci określić, jak bardzo ziarnisty chcesz to zrobić. Więc jeśli chcesz usunąć pliki od a do o i Z, możesz użyć:

rm [a-o,z]*
```.
1
1
1
2013-04-01 12:44:13 +0000

Jeszcze inna wersja z użyciem xargs:

ls -1 | grep -v do_not_delete | xargs -I files rm "files"

Zauważ, że xargs -I jest potrzebne do poprawnej obsługi nazw plików zawierających spacje.

0
0
0
2013-10-22 07:06:44 +0000

Prosty sposób, który trudno zepsuć: powiedzmy, że chcesz usunąć wszystko oprócz pliku *.pdf:

mkdir tmp
mv *.pdf tmp
rm *
mv tmp/* .
rm -r tmp