Odpowiedzi:
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
.pdfw nazwie plikuNa przykład, jeśli tempw twoim katalogu domowym znajduje się katalog:
cd ~/temp
następnie usuń pliki:
find . -type f ! -iname "*.pdf" -delete
Spowoduje to usunięcie wszystkich plików oprócz xyz.pdf.
Możesz połączyć te dwa polecenia, aby:
find ~/temp -type f ! -iname "*.pdf" -delete
.jest bieżącym katalogiem. !oznacza zabranie wszystkich plików oprócz tych .pdfna końcu. -type fwybiera tylko pliki, a nie katalogi. -deleteoznacza go usunąć.
!musi przyjść wcześniej -name. po prostu -namebędzie zawierać tylko .pdf, podczas gdy -inamebędzie zawierać zarówno .pdfi.PDFAby usunąć tylko w bieżącym katalogu, a nie w podkatalogach, dodaj -maxdepth 1:
find . -maxdepth 1 -type f ! -iname "*.pdf" -delete
.oznacza bieżący katalog. !oznacza, że weźmiesz wszystkie pliki oprócz tego .pdfna końcu. -deleteoznacza go usunąć. czy jestem teraz czysty?
-maxdepth 1parametr na początek. Następnie zasugeruj usunięcie parametru, jeśli chcesz usunąć rekurencyjnie.
Dzięki bashrozszerzeniu globowania powłoki możesz usunąć wszystkie pliki z rozszerzeniami innymi niż .pdfza pomocą
rm -- *.!(pdf)
Jak zauważono w @pts, --znaki wskazują koniec dowolnych opcji poleceń, dzięki czemu polecenie jest bezpieczne w rzadkich przypadkach plików, których nazwy zaczynają się od -znaku.
Jeśli chcesz usunąć pliki bez żadnego rozszerzenia, a także pliki z rozszerzeniami innymi niż .pdf, to jak wskazał @DennisWilliamson, możesz użyć
rm -- !(*.pdf)
Rozszerzone globowanie powinno być domyślnie włączone, ale jeśli nie, możesz to zrobić za pomocą
shopt -s extglob
Zwłaszcza, jeśli zamierzasz użyć tego w skrypcie, ważne jest, aby pamiętać, że jeśli wyrażenie nie pasuje do niczego (tj. Jeśli w katalogu nie ma plików innych niż pdf), wówczas domyślnie glob zostanie przekazany do pliku rmpolecenie, co powoduje błąd podobny do
rm: cannot remove `*.!(pdf)': No such file or directory
Możesz zmodyfikować to domyślne zachowanie za pomocą nullglobopcji powłoki, jednak ma to swój problem. Aby uzyskać dokładniejszą dyskusję, zobacz NullGlob - Wiki Grega
rm *~*.pdf
!(*.py). Prawdopodobnie, jeśli OP chce pozostać tylko plikami „.pdf”, pliki bez rozszerzeń również powinny zostać usunięte i nie powinny być ignorowane.
$ cd <the directory you want>
$ gvfs-trash !(*.pdf)
Lub za pomocą mvpolecenia (ale w ten sposób nie można przywrócić go z Kosza, ponieważ nie rejestruje on informacji .trashinfo, więc oznacza to, że przeniesiono pliki do miejsca docelowego, w którym znajduje się poniżej).
mv !(*.pdf) ~/.local/share/Trash/files
rm.
Najłatwiejsze podejście: Utwórz gdzieś inny katalog (jeśli usuwasz tylko w jednym katalogu, a nie rekurencyjnie, może to być nawet podkatalog); przenieś tam wszystkie pliki .pdf; usuń wszystko inne; cofnij plik pdf do tyłu; usuń katalog pośredni.
Szybko, łatwo, możesz dokładnie zobaczyć, co robisz. Upewnij się tylko, że katalog pośredni znajduje się na tym samym urządzeniu co katalog, który czyścisz, aby ruchy były nazwami, a nie kopiami!
Użyj GLOBIGNORE bash:
GLOBIGNORE=x.pdf:a.pdf
rm *
unset GLOBIGNORE
Ze strony podręcznika użytkownika bash:
GLOBIGNORE:
Rozdzielona dwukropkami lista wzorców definiujących zestaw
nazw plików, które mają zostać zignorowane przez rozwinięcie nazwy ścieżki.
Szybki test:
mkdir /tmp/foooooo
cd /tmp/foooooo
touch x.pdf y.zip z.mp3 a.pdf
GLOBIGNORE=x.pdf:a.pdf
ls -1 *
Wynik:
y.zip z.mp3
Oto podejście mi się podoba, bo to pozwala mi być bardzo ostrożny: komponować sposób, aby pokazać tylko te pliki, które chcę usunąć, a następnie wysłać je do rmkorzystania xargs. Na przykład:
ls pokazuje mi wszystkols | grep pdfpokazuje mi pliki, które chcę zachować. Hmmls | grep -v pdfpokazuje coś przeciwnego: wszystko oprócz tego, co chcę zachować. Innymi słowy, pokazuje listę rzeczy, które chcę usunąć. Mogę to potwierdzić, zanim zrobię coś niebezpiecznego.ls | grep -v pdf | xargs rmwysyła dokładnie tę listę do rmusunięciaJak powiedziałem, podoba mi się to przede wszystkim ze względu na bezpieczeństwo: nie przypadek rm *dla mnie. Dwie inne zalety:
lslub, findaby uzyskać początkową listę, jak wolisz. Możesz zawęzić wszystko, co chcesz, w trakcie zawężania tej listy - inną grep, inną awklub cokolwiek innego. Jeśli chcesz usunąć tylko pliki, których nazwy zawierają kolor, możesz zbudować go w ten sam sposób.finddo wyszukiwania i rmusuwania, zamiast pamiętać, że findakceptuje -deleteflagę. A jeśli to zrobisz, ponownie możesz skomponować alternatywne rozwiązania; może zamiast tego rmmożesz utworzyć trashpolecenie, które przenosi plik do kosza (umożliwiając „usunięcie”) i potokuje do niego zamiast rm. Nie potrzebujesz findobsługi tej opcji, po prostu do niej potokujesz.Zobacz komentarze @pabouk, aby dowiedzieć się, jak to zmienić, aby obsługiwać niektóre przypadki krawędzi, takie jak podziały linii w nazwach plików, nazwy plików my_pdfs.zipitp.
pdfdowolne miejsce w jego nazwie. --- b) Usunie pliki PDF, jeśli dowolna litera w sufiksie jest wielka. --- c) Nie jest dobrym pomysłem używanie wyjścia ls. Nie będzie działać z nazwami plików zawierającymi znaki nowej linii. Niektóre implementacje lszamiany znaków specjalnych, np. Tab by ?. --- Lepiej jest użyć: find -maxdepth 1 -print0. (nie tak krótki jak ls:) ----- Aby rozwiązać a) ib) użyj grep -vi '\.pdf$'--- kompletne (ale tylko GNU) rozwiązanie:find -maxdepth 1 -print0 | grep -viz '\.pdf$' | xargs -0 rm
| head -20przynajmniej sprawdzić, czy wygląda mniej więcej poprawnie, a jeśli tak rm my_pattern, nie masz szansy na zauważenie dużego błędu.
find . -type f ! -name "*.pdf"do drukowania na konsoli, lub potokuj do mniejszej lub pliku. [a następnie potokuj do xargs do rm, jeśli chcesz, tak jak komentarze pabouk (z -print0 | ... -0 dla dziwnych nazw plików)]
Zwykle rozwiązuję takie problemy z interaktywnego interpretera Pythona:
mic@mic ~ $ python
>>> import os
>>> for f in os.listdir('.'):
... if not f.endswith('.pdf'):
... os.remove(f)
Może być dłuższy niż jednowarstwowy z findlub xargs, ale jest bardzo odporny i wiem dokładnie, co robi, bez konieczności wcześniejszego badania.
for item in [f for f in os.listdir('.') if not f.endswith('.pdf')]: os.remove(item)
python -c "import os; for f in os.listdir('.'): if not f.endswith('.pdf'): os.remove(f)"
[os.remove(f) for f in os.listdir('.') if not f.endswith('.pdf')]
lepszą odpowiedzią (w porównaniu do mojej poprzedniej odpowiedzi) na to pytanie będzie użycie potężnego filepolecenia.
$ file -i abc.pdf
abc: application/pdf; charset=binary
teraz twój problem:
cd <the directory you want to search in>
for var in ./*
do
if file -i "$var" | grep -q 'application/pdf\;'
then
echo "$var"
fi
done
zadaniem forpolecenia jest podanie plików w bieżącym katalogu w postaci zmiennej $var. if-thenpolecenie wyświetla nazwy plików pdf, biorąc status wyjścia 0z file -i "$var" | grep -q 'application/pdf\;'polecenia, daje status wyjścia 0tylko wtedy, gdy znajdzie pliki pdf.
rm $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
Ostrzeżenie! Lepiej najpierw spróbuj
ls -l $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
-iz grepdo dopasowywania bez rozróżniania wielkości liter.
rm -i -- !(*@(a|x).pdf)
Czytaj jako, usuń wszystkie pliki, które nie są a.pdflub x.pdf.
Działa poprzez wykorzystanie 2 wydłużonych globs zewnętrzna !()negacji zawartego glob, który z kolei wymaga, aby do wzorca, musi być zgodny z jednym lub więcej alub xstanie przed .pdfkońcówką. Zobacz glob # extglob .
$ ls -a
.dotfile1 .dotfile2 a.pdf x.pdf y.zip z.mp3
$ echo -- !(a.pdf)
-- x.pdf y.zip z.mp3
$ echo -- !(x.pdf)
-- a.pdf y.zip z.mp3
$ echo -- !(a.pdf|x.pdf)
-- y.zip z.mp3
$ echo -- !(@(a|x).pdf) # NOTE.that this matches the .dotfiles* as well
-- . .. .dotfile1 .dotfile2 y.zip z.mp3
$ echo -- !(*@(a|x).pdf) # but this doesn't
-- y.zip z.mp3
$ echo rm -i -- !(*@(a|x).pdf)
rm -i -- y.zip z.mp3
$ ksh -c 'for i in ./*; do case $i in *.pdf)continue;; *)rm "$i";; esac;done'
Dość dużo POSIX i kompatybilny z dowolnym powłoce Bourne'a Style ( ksh, bash, dash). Dobrze nadaje się do przenośnych skryptów i gdy nie możesz użyć bashrozszerzonego globowania powłoki.
$ perl -le 'opendir(my $d,"."); foreach my $f (grep(-f && !/.pdf/ , readdir($d))){unlink $f};closedir $d'
Lub nieco czystszy:
$ perl -le 'opendir(my $d,"."); map{ unlink $_ } grep(-f "./$_" && !/.pdf/ , readdir($d));closedir $d'
python -c 'import os;map(lambda x: os.remove(x), filter(lambda x: not x.endswith(".pdf"),os.listdir(".")))'
Uważaj na to, co usuwasz!
Bezpiecznym sposobem przetestowania go przed próbą usunięcia jest przetestowanie go najpierw ls, ponieważ niektóre nieprzechwycone zachowania mogą usuwać niechciane pliki. Możesz to zrobić bezpośrednio poza katalogiem. lsjest podobny do rm, więc:
ls sub/path/to/files/!(*.pdf)
Spowoduje to wyświetlenie listy
y.zip
z.mp3
Teraz możesz zobaczyć, co usuwasz, i możesz je bezpiecznie usunąć:
rm sub/path/to/files/!(*.pdf)
I to wszystko. Możesz używać symboli wieloznacznych, *aby być bardziej selektywnym, tak jak przechowywanie tylko dokumentów kursu programowania:
rm sub/path/to/files/!(*programming*)
.oznacza „i”?!oznacza „oprócz”-nameoznacza, że chcesz wykluczyć za pomocą parametru nazwy, a następnie-deleteczy należy podjąć działanie po znalezieniu? Więc szuka wszystkiego oprócz „* .pdf” i usuwa je? A może źle zrozumiałem?