Usuwanie wszystkich plików w folderze oprócz plików X, Y i Z


17

Mam wiele plików i folderów w określonym folderze i chcę je wszystkie usunąć; chciałem jednak zachować pliki X, Y i Z.

Czy mogę zrobić coś takiego: rm * | but NOT grep | X or Y or Z


Zakładam, że mogę użyć jakiegoś wyrażenia regularnego, które to zrobi?
Amit

Odpowiedzi:


16

Zamiast używać rm, może być łatwiej użyć find . Takie polecenie usunie wszystko oprócz pliku o nazwie dokładnie „plik”

find . \! -name 'file' -delete

Wiele wersji powinno być w stanie obsługiwać globowanie i dopasowanie wyrażeń regularnych.

Możesz także przesłać dane wyjściowe find do rm

find . \! -name '*pattern*' -print0 | xargs --null rm 

3
Pozwala to zobaczyć dokładnie, jakie pliki zostaną usunięte poprzez usunięcie -deleteoraz jakie pliki zostaną zapisane poprzez usunięcie -deletei \!.
Shawn J. Goff,

1
ostrożny, findjest rekurencyjny! więc wszystkie podkatalogi plików, które nie pasują do „ wzorca ”, również zostaną usunięte
Alexandre Holden Daly

Sposób przez xargs wymaga -depth, aby zapobiec próbie usunięcia katalogów przed zawartymi w nich plikami. Myślę jednak, że rm również nie usunie katalogów.
użytkownik nieznany

9

Używanie zsh, z setopt EXTENDED_GLOB, używanie ~operatora ( oprócz )

rm -- *~(x|y|z)

lub ^operator (negacja):

rm -- ^(x|y|z)

Ale prawdopodobnie powinieneś zamiast tego przenieść pliki w inne miejsce, a następnie usunąć wszystko. Jest o wiele bezpieczniejszy pod względem poślizgnięć palców, takich jak zbyt wczesne trafienie.


5

Późniejsze wersje bash mają extglobopcję powłoki, która daje ci składnię do robienia tego, co chcesz (sprawdź swoją stronę podręcznika w „Pathname Expansion”, aby zobaczyć, czy ma ją zainstalowana wersja):

$ shopt -s extglob  # turn on extended globbing
$ rm !(X|Y|Z)

Aby przetestować, proponuję najpierw wymienić rmze echoaby sprawdzić, czy lista plików, które mają zostać usunięte, co można się spodziewać.


5
ls -1 | grep -v "^[XYZ]$" # | xargs rm -r

Uwaga: Uruchom polecenie i jeśli pliki do usunięcia są odpowiednie, uruchom je ponownie i usuń znak krzyżyka „#”.

Jeśli nazwy plików są bardziej skomplikowane, zrób to

ls -1 | egrep -v "^file1$|^filename2$|^f1le$" # | xargs rm -r

Ponownie, spójrz najpierw na wyniki, a następnie usuń znak skrótu.

Ta wersja - jak sugerowano w komentarzach - zapisuje niektóre postacie i wygląda nieco jaśniej.

ls -1 | egrep -v "^(file1|filename2|f1le)$" # | xargs rm -r

Sugerowaną edycją ddeimeke jest zmiana egrepargumentu na"^(file1|filename2|f1le)$"
Michael Mrozek

Jeśli masz trzy pliki a, ba a bpierwszy program usunie - jeśli umieścisz ab do części grep: "^[ab]$" aa bjednak nie a b, po prostu w przeciwieństwie do swoich zamiarów. Drugie polecenie zrobi to samo. I trzeci też. Nie należy używać „ls” w skryptach, z bardzo, bardzo rzadkimi wyjątkami. Po prostu nie rób tego.
użytkownik nieznany

3

Przenieś pliki, które chcesz zachować. Przejdź o jeden poziom wyżej, usuń folder. Utwórz ponownie folder i przenieś te pliki z powrotem.


Zastanawiam się, dlaczego minus? .. Jest to w rzeczywistości zarówno łatwiejsze, jak i bezpieczniejsze niż cokolwiek proponowanego przez innych: po prostu nie możesz strzelić sobie w stopę, naciskając specjalny znak w nazwie pliku.
alex

a) Przenosisz plik X jeden katalog w górę, gdzie istnieje plik X - po cichu usunięty, zniknął. b) Jesteś w najlepszym katalogu, w którym nie ma „up”. c) Jesteś w swoim domu, i nie ma uprawnień do zapisu w katalogu / home. Jeśli umieścisz swoją radę w skrypcie i przetestujesz ją bez problemu i wykorzystasz w takiej sytuacji - peng!
użytkownik nieznany

2
a) Hej, czy powiedziałem „przenieś pliki o jeden poziom wyżej ”? Powiedziałem, odsuń je. b) Więc próbujesz usunąć wszystkie pliki /, heh? Niezbyt praktyczne. c) Próba usunięcia wszystkich plików z twojego pliku również $HOMEnie jest zbyt praktyczna.
alex

Masz rację, przepraszam.
użytkownik nieznany

0

To właśnie skonfigurowałem jako skrypt .sh dla haka do wylogowywania OSX / MacOS, działa wystarczająco dobrze.

#! /bin/bash
for dir in /PathToFolder/*
 do
    if [ ! "$dir" = "/PathToFolder/FolderToKeep1" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep2" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep3" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep4" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep5" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep6" ] ; then 
      echo ${dir}
      sudo rm -R $dir user
      dscl . -delete $dir
    fi 
  done

exit 0

0

Za pomocą GNU-find możesz użyć przełącznika -delete, który usuwa również katalogi, jeśli są również puste:

 find tmp -not -name X -not -name Y -not -name Z -delete 

Jeśli X, Y lub Z to katalog, spowoduje to również usunięcie plików w nim zawartych. find tmp -maxdepth 1 -not -name X -not -name Y -not -name Z -deletejest jednym ze sposobów obejścia tego.
Gilles „SO- przestań być zły”

Ponieważ foldery w Uniksie są plikami (wszystko jest plikiem), być może to jest zamierzone. Pytanie wyraźnie mówi: „Mam wiele plików i folderów w określonym folderze i chcę je wszystkie usunąć;” - a jeśli chcesz wykluczyć Y, być może wiesz, czy Y jest katalogiem, czy nie.
użytkownik nieznany

Skończy się to również usunięciem, tmpjeśli nie będzie w nim plików X/ Y/ Z. Uwaga !jako standardowy odpowiednik GNU -not( -deletejest także rozszerzeniem GNU)
Stéphane Chazelas,

@ StéphaneChazelas: Z pytania wynika, że ​​poproszono o usunięcie folderów (wszystkich). Ponieważ huk wymaga maskowania, wolę pisać - nie. Może zależeć od niemieckiego układu klawiatury, gdzie Backslash wymaga Alt-Gr.
użytkownik nieznany
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.