Zdaję sobie sprawę, że każde pytanie dotyczące usuwania plików należy rozwiązywać bardzo ostrożnie. Moja pierwsza odpowiedź była zbyt pochopna. Nie wziąłem pod uwagę, że lista plików może być zniekształcona do użycia z egrep. Zredagowałem odpowiedź, aby zmniejszyć to ryzyko.
To powinno działać dla plików, które nie mają spacji w nazwie:
Najpierw odbuduj listę plików, aby mieć pewność, że dokładnie pasuje do nazwy pliku:
sed -e 's,^,^,' -e 's,$,$,' filelist > newfilelist
buduj komendy rm
cd your_directory
ls | egrep -vf newfilelist | xargs -n 1 echo rm > rmscript
Sprawdź, czy skrypt rm Ci odpowiada (Możesz to zrobić za pomocą „vim” lub „mniej”).
Następnie wykonaj akcję:
sh -x rmscript
Jeśli pliki mają spacje w nazwie (jeśli pliki mają "
w nazwie to to nie zadziała):
ls | egrep -vf newfilelist | sed 's,^\(.*\)$,rm "\1",' > rmscript
oczywiście lista plików nie powinna znajdować się w tym samym katalogu!
EDYTOWANE:
Lista plików Nathana zawierała nazwy pasujące do wszystkich plików w katalogu (np. „Html” pasuje do „bob.html”). Więc nic nie zostało usunięte, ponieważ egrep -vf
pochłonęło cały strumień. Dodałem polecenie umieszczenia „^” i „$” wokół nazwy każdego pliku. Miałem szczęście, że lista akt Nathana była poprawna. Gdyby był sformatowany w systemie DOS z zakończonymi liniami CR-LF lub z dodatkowymi spacjami, żadne pliki nie byłyby zachowane przez egrep i wszystkie zostałyby usunięte.
ls
zapewnia nazwy plików katalogów,egrep -vf filelist
odfiltruj 50 nazw plików. Obawiam się, że usunąłeś wszystkie swoje pliki.Wstępnie konstruuj argumenty, aby
find
:Użyj
echo
części, aby zobaczyć, co zostanie zbudowane. Wyjmijecho
części, aby faktycznie je uruchomić.Aktualizacja: Demonstracja:
źródło
'
) należy dodać to znaczykeep=( -name \'"$REPLY"\' )
akeep+=( -o -name \'"$REPLY"\' )
.Z
zsh
:Odczytuje wiersze z
filelist
tablicy, a następnie używa glob qualifiers /e
string do glob / zaznacz tylko te nazwy plików, których nie ma w tablicy:.
zaznacza tylko zwykłe pliki (dodaj,D
jeśli twoja lista zawiera pliki kropkowe), a negacja^e_'expression'_
dalej wybiera tylko te dla którego wyrażenie zwraca false, tzn. jeśli ich nazwa ($REPLY
) nie jest elementem tablicy .Jeśli jesteś zadowolony z wyniku zastąpienia
print -rl
zrm
faktycznie usunąć pliki:Aby rekurencyjnie wybierać i usuwać pliki, użyj
*/**
glob z${REPLY:t}
modyfikatorem glob:źródło
Jeśli umieścisz zawartość katalogu w takim pliku:
Otwórz listę plików za pomocą edytora tekstu i usuń wszystkie pliki oprócz tych, które CHCESZ USUNĄĆ . To jest pogrubione, ponieważ jest to odwrotne podejście do powyższej odpowiedzi
Spróbuj tego:
Jeśli zobaczysz listę plików wyprowadzanych na ekran, zamień echo na
rm -v
:źródło
Uruchom poniższy skrypt.
all_files
.not_to_be_deleted_files
).not_to_be_deleted_files
ifiles_to_be_deleted
na koniec,not_to_be_deleted_files
ponieważ potrzebujemy tych 2 plików.join
polecenia linux i przekierowuję dane wyjściowe dofiles_to_be_deleted
pliku.files_to_be_deleted
i usuwam pliki wymienione w tej nazwie pliku.Skrypt jest jak poniżej.
PS : Prawdopodobnie, jeśli chcesz to zapisać jako skrypt i uruchomić, możesz także dodać nazwę skryptu, używając
echo scriptname >> not_to_be_deleted_files
.Chociaż nie jest to wymagane, wolę to zrobić, ponieważ później nie będzie żałować. Testowałem mały zestaw plików i działał on w moim systemie. Jeśli jednak chcesz się upewnić, spróbuj
test
najpierw w katalogu, a następnie usuń pliki z oryginalnego katalogu.źródło
źródło
Wybrałem bezpieczniejsze i znacznie szybsze podejście, ponieważ miałem na liście 18 000 plików! Musiałem wyczyścić obrazy w dużej instalacji Drupala.
Usunięcie wszystkich plików, których nie ma na liście, jest tym samym, co zachowanie tylko tych, które są na liście. Postanowiłem więc skopiować pliki z listy do innej lokalizacji, ale skopiowanie 20 GB plików zajęłoby zbyt dużo miejsca i byłoby bardzo powolne. Sztuką jest więc skopiowanie plików
hardlinks
zamiast tego, używając-l
opcjicp
. To nie zajmuje prawie miejsca i jest bardzo szybkie. Dodatkowo, ponieważ musiałem zachować strukturę katalogów, skorzystałem z tej--parents
opcji.Oto fragment mojej listy plików:
Przykładem może być wiersz z tempem jako miejscem docelowym:
Spowoduje to utworzenie tej struktury:
Zauważ, że miejsce docelowe musi znajdować się w tym samym systemie plików co źródło twardych dowiązań do działania.
Następnym krokiem jest zbudowanie skryptu:
Teraz, zakładając, że utworzyłeś już pusty katalog / some / where / temp, możesz skopiować pliki w następujący sposób:
Zwróć uwagę, w jaki sposób błędy się kończą
missing_files
. Dodatkową zaletą tego podejścia jest to, że otrzymasz listę plików z oryginalnej listy, które tak naprawdę nie istnieją!Po uruchomieniu skryptu temp będzie zawierać tylko te pliki, które znajdują się na liście plików, ale bez usuwania czegokolwiek i bez zajmowania dodatkowego miejsca. Jeśli wynik jest zadowalający, możesz usunąć wszystkie oryginalne pliki, w tym podfoldery.
Na koniec przenieś pliki i foldery z temp z powrotem do pierwotnej lokalizacji.
W przypadku 18 000 plików zajęło to tylko kilka sekund.
źródło
Bezpiecznie, prosto.
cd
do katalogu.Utwórz katalog tymczasowy.
gotowy.
źródło