Bir deseni glob eşlemesinden hariç tut


53

Aynı temel dosya adına sahip birkaç dosyam var. Biri dışındaki tümünü kaldırmak istiyorum

foo.org #keep
foo.tex #delete
foo.fls #delete
foo.bib #delete
etc

Bir tane tutmak zorunda kalmazsam, kullanabileceğimi biliyorum rm foo.*.

TLDP eşleşmeyi reddettiğini gösterdi ^. Deneme ve yanılma yoluyla bunu bulabildim

rm foo.*[^org]

ihtiyacım olanı yapıyor, ancak sözdizimini gerçekten anlamıyorum.

Ayrıca kullanımım durumda değil bir sınırlama ise, bu desen de görmezden düşünüyorum foo.ove foo.or. Nasıl ve ne bir topak bu desen çalışması yoksayar ümit etmesi sadece foo.org benziyor?


1
O belirtmek gerekir cevap @glen istinaden ilave olarak rm foo.*[^org]tüm dosyaları siler son ne karakterdir o, rya g, bu yüzden foo.fooeşler olmaz.
jimmij

Bir kullanıyorsunuz Regular Expression. Gruplandırma karakterlerine dikkat etmelisin. Parantez kullanarak, bir harflerle uzantısı vardı herhangi bir dosyayı silmek olacak bir karakter sınıfı anlam belirttiğiniz o, rya gherhangi bir sırada. Bir grup oluşturmak ve karakter sırasını korumak için parantez kullanın.
Bay Mascaro

3
@ jbarker2160 - bu gerçekten normal bir ifade değil, daha genel olarak normal bir ifadenin alt kümesi olan bir glob (veya dosya adı modeli ) olarak adlandırılır - ayrıntılar için bash sayfasının desen eşleme bölümüne bakın. Deseni , son karakterin o, r veya g olmadığı noktadan sonra bir veya daha fazla karakterle foo.*[^org]başlayan herhangi bir dosya adıyla eşleşir foo.. Bu yüzden maç olur foo.orbama foo.orgya foo.orya foo.o. GlennJackman'ın cevabı, bir eşleşmeyi yok etmek için genişletilmiş desen eşleştirme özelliklerinin nasıl etkinleştirileceğini gösterir.
Johnny

Yanıtlar:


52
shopt -s extglob
echo rm foo.!(org)

Bu "foo". "ORG" DEĞİL bir şey izledi

ref: https://www.gnu.org/software/bash/manual/bashref.html#Pattern-Matching


Aynısını yapmaya çalıştım ama parantez ile ve görünüşe göre parantez kullanırken işe yaramadı
Donato

4
Birden fazla dosya adıyla eşleşecek sözdizimi nedir? .org, .png, .txt dosyasının dışlanmasını istediğimi
Freedo,

@()Bir kalıp listesi için @Freedo : stackoverflow.com/a/217208/3779853
phil294

23

Bash'ta da kullanabilirsiniz GLOBIGNORE="*.org"; rm -i foo*.

Ve unset GLOBIGNOREbittiğinde.

Bundan daha iyi değil shopt -s extglob, ama hatırlamayı daha kolay buluyorum.


5
@Ruslan Bu çalışmıyor. Sen yapmalıyım( GLOBIGNORE="*.org"; rm -i foo* )
DBedrenko

3
Eğer göz ardı listesini genişletmek gibi, iki nokta üst üste ile ayırmak istiyorsanız NotGLOBIGNORE="*foo*:*bar*"
phyatt

7

Bir boru yapabilir?

ls * | grep -v "foo.org" | xargs -I {} echo {}

(Açıkçası, son yankıdaki yankıyı rm ile değiştirmek isteyebilirsiniz).


Sadece bir satırda gerektiğinde kullanışlıdır.
bruceskyaus

1
Hatırlaması daha kolay (benim için sık sık böyle şeyler yapıyorum) ve daha karmaşık işlemlerin
başlatılmasını sağlar

1
ls -1tüm dosyaların grepayrı ayrı ele alındığından emin olmak için daha güvenilir olması gerekir
MichaelChirico

0

OP çok yakındı:

rm foo.*[^o][^r][^g]

Yine de bu durumda *gereksiz.

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.