Linux'ta tüm dosyalar nasıl silinir EXCEPT pattern * .txt?


73

txtŞu anki dizindeki tüm dosyaları nasıl sileceğimi biliyorum rm *.txt. EXCEPT txtdosyasındaki mevcut dizindeki tüm dosyaları nasıl sileceğimi bilen var mı ?


20
Her zaman olduğu gibi, verilen yanıtları lsaslında aramaya başlamadan önce olduğu gibi zararsız bir komutla test edin rm.
chepner

Yanıtlar:


111

Kullanabilirsiniz find:

find . -type f ! -name '*.txt' -delete

Veya bash'in genişletilmiş globbing özellikleri:

shopt -s extglob
rm *.!(txt)

Veya zsh cinsinden:

setopt extendedglob
rm *~*.txt(.)
#  ||     ^^^ Only plain files
#  ||^^^^^ files ending in ".txt"
#  | \Except
#   \Everything

Bunlardan bazılarının, klasörlerin olup olmadığına ve onlarla ne yapmak istediğinize bağlı olarak uyarlanması gerekebilir.
Kevin

1
Gerekmiyor *.!(txt)olmak !(*.txt)?
Lri

@LauriRanta, cevap alamadığımız klasörde ne olduğuna bağlıdır. Tüm dosyaların uzantıları rmvarsa ve klasör olsaydı boğulacak gibi olur.
Kevin,

Desteklerle ilgili bir sorunum var. Globbing stilini bir bash betiğinde kullandığımda, sözdizimi hatası ve parantezlerden şikayetçi. Ancak CLI işleri yapıyor.
CMCDragonkai

1
@izogfif bunun find . -type f ! -name "*.txt" | xargs -r rmGNU \ xargs içinde çalışıp çalışmadığını kontrol edin . BSD ve UNIX xargs komutunda olmayabilir -r man xargs
yerelinizi

10

'* .Txt' dışındaki tüm dosyaları silmek istiyorsanız , aşağıdaki komutu kullanabilirsiniz:

$ find . -type f ! -name "*.txt" -exec rm -rf {} \;

ancak dosyaları da birlikte dizinleri silmek istiyorsanız, o zaman bunu kullanabilirsiniz:

$ find . ! -name "*.txt" -exec rm -r {} \;


9

Bunu yapmanın birçok yolu var. ama en basit yol şudur (bash):

shopt -s extglob
rm !(*.txt)

4

Olmadan bir çözüm find:

mv dir/*.txt otherdir/
rm -r dir
mv otherdir dir

Bu her türlü mermi üzerinde çalışmalı.


3

Ters grep ve xargs kullanabilirsiniz

ls | grep -v .txt$| xargs rm

ls | grep -v *.txt | xargs rmaynı şekilde çalışır
phillipsk

@phillipsk grep -v *.txtyalnızca tam olarak bir .txtdosya varsa çalışır . Yok ise, desen olarak grepkullanacaktır *.txt; birden fazla varsa, diğer .txtdosyaların içindeki ilk dosya adını arayacak ve çıktıyı görmezden gelecek ls. (Kesin sonuçlar kabuğun glob seçeneklerine bağlı olabilir.)
JigglyNaga

.txt$txtnoktadan bağımsız olarak biten karakter dizileriyle eşleşir . Çünkü grepnormal ifadeyi parametre olarak alır. Yani dosyalar a.txtve aatxtve a-txttüm bu ifadesinin eşleştiği edilecektir. Doğru ifade olmalı ls | grep -v \\.txt$ | xargs --no-run-if-empty rm. Meraklı insanlar için: İfade ile oynamak istiyorsanız, bu test ifadesini güvenle kullanın ls | grep \\.txt$ | xargs --no-run-if-empty echo(not: -vbayrak yok ve rm=>echo). Not2: Çift ters eğik çizgi görmüş olabilirsiniz. Biri regex içindir, diğeri bash'ın eğik çizgiden kaçması içindir.
Dimitry K

1

Basitçe yapın:

rm $(ls -I "*.txt" ) # * .Txt dışında dosya türünü siler

Aynı şekilde, "bir veya daha fazla dosya türü hariç" silmek zorundaysanız, şunları yapın:

rm $(ls -I "*.txt" -I "*.pdf" ) # * .Txt & * .pdf dışındaki dosya türlerini siler


StackExchange'e Hoş Geldiniz! Bu -Iseçenek faydalı olabilir, ancak neden ayrıştırmadığınızı görün . Ve ne başarır | xargs? Herhangi bir argüman olmadan, sadece echotüm girdilerle çalışır .
JigglyNaga,

Neyi xargsbaşarması gerekiyor?
dhag,

Teşekkürler, yukarıdaki durumda Xargs kullanışlı değildi, şimdi düzeltildi.
Surya

0

Bu ayrıca belirtilen ( ) dışındaki tüm gizli (nokta) dosya ve klasörleri kaldırmak için de çalışır .mydir:

rm -rf $(ls -aI ".mydir")
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.