Aşağıdakileri içeren bir dizini var:
x.pdf
y.zip
z.mp3
a.pdf
Ben dışında tüm dosyaları silmek istiyor x.pdf
ve a.pdf
. Bunu terminalden nasıl yaparım? Hiçbir alt dizin bulunmadığından herhangi bir özyinelemeye gerek kalmaz.
Aşağıdakileri içeren bir dizini var:
x.pdf
y.zip
z.mp3
a.pdf
Ben dışında tüm dosyaları silmek istiyor x.pdf
ve a.pdf
. Bunu terminalden nasıl yaparım? Hiçbir alt dizin bulunmadığından herhangi bir özyinelemeye gerek kalmaz.
Yanıtlar:
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
.pdf
dosya içindeÖrneğin, temp
giriş klasörünüzde adı verilen bir dizin varsa :
cd ~/temp
sonra dosyaları silin:
find . -type f ! -iname "*.pdf" -delete
Bu hariç tüm dosyaları silecektir xyz.pdf
.
Bu iki komutu aşağıdakilerle birleştirebilirsiniz:
find ~/temp -type f ! -iname "*.pdf" -delete
.
Geçerli dizin. Sonunda !
olanlar hariç tüm dosyaları almak anlamına gelir .pdf
. -type f
dizinleri değil, sadece dosyaları seçer. -delete
silmek anlamına gelir.
!
daha önce gelmelisin -name
. basitçe -name
sadece içerecektir .pdf
ederken, -iname
içerecektir .pdf
ve.PDF
Yalnızca geçerli dizinde silmek ve alt dizinlerde silmek için şunu ekleyin -maxdepth 1
:
find . -maxdepth 1 -type f ! -iname "*.pdf" -delete
.
geçerli dizin anlamına gelir. sonunda !
olanlar hariç tüm dosyaları almak anlamına gelir .pdf
. -delete
silmek anlamına gelir. şimdi temiz miyim
-maxdepth 1
Başlamak için parametreyi dahil etmiş olmalısınız . Ardından, yinelemeli olarak silmek istemeniz durumunda parametrenin çıkarılmasını önerin.
İle bash
'genişletilmiş kabuk globbing, seni dışındaki uzantılı dosyaları kaldırmak olabilir .pdf
kullanılarak
rm -- *.!(pdf)
Pts tarafından belirtildiği gibi, --
karakterler herhangi bir komut seçeneğinin sonunu belirtir, adı bir -
karakterle başlayan ender dosyalarda komutu güvenli hale getirir .
Herhangi bir uzantıya sahip olmayan dosyaların yanı sıra uzantıları dışındaki dosyaların da silinmesini istiyorsanız .pdf
, @DennisWilliamson tarafından belirtildiği gibi
rm -- !(*.pdf)
Genişletilmiş globbing varsayılan olarak etkin olmalıdır, ancak eğer
shopt -s extglob
Özellikle bunu bir betiğin içinde kullanmayı düşünüyorsanız, ifadenin hiçbir şeyle eşleşmemesi durumunda (yani dizinde pdf dosyası bulunmuyorsa), o zaman varsayılan olarak dünyaya genişletilmiş olarak geçilir. rm
komutu gibi bir hataya neden
rm: cannot remove `*.!(pdf)': No such file or directory
Bu varsayılan davranışı nullglob
shell seçeneğini kullanarak değiştirebilirsiniz , ancak bunun kendi sorunu vardır. Daha ayrıntılı bir tartışma için bkz. NullGlob - Greg's Wiki
rm *~*.pdf
!(*.py)
. Ayrıca, muhtemelen OP sadece ".pdf" dosyalarının kalmasını istiyorsa, uzantısız dosyaları da silinmeli ve göz ardı edilmemelidir.
$ cd <the directory you want>
$ gvfs-trash !(*.pdf)
Veya mv
komut aracılığıyla (ancak bu şekilde .trashinfo bilgilerini kaydetmediğinden Çöp'ten geri yükleyemezsiniz, bu nedenle dosyalarınızı aşağıdaki gibi bir hedefe taşıdığınız anlamına gelir ).
mv !(*.pdf) ~/.local/share/Trash/files
rm
.
En kolay yaklaşım: Bir yerde başka bir dizin oluşturun (yalnızca bir dizinde siliyorsanız, yinelemeli değil, bir alt dizin bile olabilir); orada tüm .pdf's taşımak; her şeyi sil; pdf'in arkasını oynatın; ara dizini silin.
Çabuk, kolay, tam olarak ne yaptığınızı görebilirsiniz. Ara dizinin, temizlediğiniz dizininkiyle aynı aygıtta olduğundan emin olun, böylece hareketler kopya değil, adlardır!
Bash adlı kişiyi kullan:
GLOBIGNORE=x.pdf:a.pdf
rm *
unset GLOBIGNORE
Bash'ın man sayfasından:
GLOBIGNORE: Kümeyi tanımlayan bir iki nokta üst üste ayrılmış desen listesi dosya adı genişletmesi tarafından göz ardı edilecek dosya adlarının listesi.
Hızlı bir test:
mkdir /tmp/foooooo
cd /tmp/foooooo
touch x.pdf y.zip z.mp3 a.pdf
GLOBIGNORE=x.pdf:a.pdf
ls -1 *
Çıktı:
y.zip z.mp3
İşte hoşuma giden bir yaklaşım, çünkü çok dikkatli olmamı sağlıyor: sadece silmek istediğim dosyaları gösterecek bir yol oluştur ve rm
kullanmaya gönder xargs
. Örneğin:
ls
bana her şeyi gösterirls | grep pdf
bana saklamak istediğim dosyaları gösteriyor. Hmm.ls | grep -v pdf
tam tersini gösterir: saklamak istediğim hariç . Başka bir deyişle, silmek istediklerimin listesini gösterir. Tehlikeli bir şey yapmadan önce bunu onaylayabilirim.ls | grep -v pdf | xargs rm
tam olarak bu listeyi rm
silmek üzere gönderirDediğim gibi, çoğunlukla sağladığı güvenlik için bunu beğendim: rm *
benim için kazara yok . Diğer iki avantaj:
ls
veya kullanabilirsiniz find
. İstediğiniz herhangi bir şeyi bu listeyi daraltma sürecinde kullanabilirsiniz - bir başkası grep
, bir kısmı awk
veya her neyse. Yalnızca adları renkli olan dosyaları silmeniz gerekirse, aynı şekilde oluşturabilirsiniz.find
bulmak ve rm
çıkarmak için kullanmayı tercih ederim . Ve bunu yaparsanız, yine alternatif çözümler oluşturabilirsiniz; belki de yerine , dosyayı çöp kutusuna taşıyan ("silinmeyi" sağlayan) ve bunun yerine pipoyu hareket ettiren bir komut oluşturabilirsiniz . Bu seçeneği desteklemene gerek yok , sadece işe yaradın.find
-delete
rm
trash
rm
find
Bunun, dosya adlarındaki satır sonları, dosya isimleri my_pdfs.zip
, vb.
pdf
Adının herhangi bir yerinde bulunan herhangi bir dosyayı dışlar . --- b) Soneki harflerden herhangi biri büyük harf ise, PDF dosyalarını siler. --- c) Çıktısını kullanmak iyi bir fikir değildir ls
. Yeni satırlar içeren dosya adlarıyla çalışmaz. ls
Özel karakterlerin yerine getirilmesinde kullanılan bazı uygulamalar, örneğin tab ?
. --- Kullanımı daha iyidir: find -maxdepth 1 -print0
. (çok kısa değil ls
:) ----- grep -vi '\.pdf$'
find -maxdepth 1 -print0 | grep -viz '\.pdf$' | xargs -0 rm
| head -20
en azından kabaca doğru görünüp görünmediğini görebilirsiniz; oysa eğer sadece rm my_pattern
büyük bir hata bulma şansınız olmaz.
find . -type f ! -name "*.pdf"
konsola yazdırmak veya daha az veya bir dosyaya aktarmak için bulmayı bulabilirsiniz . [ve daha sonra eğer pabouk'un yorumları gibi (eğer garip dosya isimleri için -print0 | ... -0 ile)
Genellikle bu tür problemleri etkileşimli Python tercümanından çözerim:
mic@mic ~ $ python
>>> import os
>>> for f in os.listdir('.'):
... if not f.endswith('.pdf'):
... os.remove(f)
Tek bir astardan daha uzun olabilir find
veya olabilir xargs
, ancak son derece dayanıklıdır ve ilk önce araştırmak zorunda kalmadan tam olarak ne yaptığını biliyorum.
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')]
daha iyi cevap (önceki cevabımla kıyaslandığında) bu soruya güçlü file
komut kullanılarak verilecek .
$ file -i abc.pdf
abc: application/pdf; charset=binary
şimdi senin problemin:
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
for
komutun görevi, geçerli dizindeki dosyaları değişken biçiminde vermektir $var
. if-then
komut 0
, file -i "$var" | grep -q 'application/pdf\;'
komuttan çıkış durumunu alarak pdf dosyalarının adlarını çıkarır , 0
yalnızca pdf dosyalarını bulursa çıkış durumunu verir .
rm $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
Uyarı! Önce denemek daha iyi
ls -l $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
-i
ile grep
küçük harf duyarsız eşleştirme için.
rm -i -- !(*@(a|x).pdf)
Oku, a.pdf
veya olmayan tüm dosyaları kaldır x.pdf
.
Bu, 2 uzatılmış globun kullanılmasıyla çalışır, dışta !()
, globun sonekten önce bir veya daha fazla a
veya x
paternle eşleşmesini gerektiren, içerdiği globu olumsuzlar .pdf
. Glob # extglob'a bakınız .
$ 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'
Herhangi Bourne tarzı kabuğu ile hemen hemen POSIX ve uyumlu ( ksh
, bash
, dash
). Portatif scriptler için uygun ve bash
uzatılmış kabuk globbing kullanamadığınızda .
$ perl -le 'opendir(my $d,"."); foreach my $f (grep(-f && !/.pdf/ , readdir($d))){unlink $f};closedir $d'
Veya biraz daha temiz:
$ 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(".")))'
Ne sildiğinize dikkat edin!
ls
Bazı yakalanmamış davranışlar istenmeyen dosyaları silebileceğinden, silmeyi denemeden önce sınamanın güvenli bir yolu önce sınamaktır . Ve doğrudan dizinin dışından yapabilirsiniz. ls
buna benzer rm
:
ls sub/path/to/files/!(*.pdf)
Bu liste olacak
y.zip
z.mp3
Artık ne sildiğinizi görebilir ve bunları güvenle silebilirsiniz:
rm sub/path/to/files/!(*.pdf)
Ve bu kadar. *
Yalnızca programlama dersi belgelerini saklamak gibi daha seçici olmak için joker kullanabilirsiniz :
rm sub/path/to/files/!(*programming*)
.
"ve" anlamına mı geliyor?!
"hariç"-name
, bir ad parametresiyle hariç tutmak istediğinizi belirtir ve ardından-delete
bulma işlemi yapılacak mı? Yani "* .pdf" dışındaki her şeyi arar ve siler mi? Yoksa yanlış mı anladım?