dosya isimlerinde kabuk genişletmesi (A | B)?


9

orÖrneğin bir dosyayı okurken kabuktaki bir seçimi genişletmek mümkün mü ?

Bununla kastettiğim, örneğin, bir dosyadaki A veya B'yi eşleştirmek grepgibi sözdizimini desteklemesi (A|B).

Benzer şekilde, bu dosyaları varsa:

file1.txt
file2.txt
file3.txt
file4.txt
file5.txt

Yapabileceğim cat file{1..5}.txtiçinde basho aralık genişledikçe,. Bunu sadece birkaç dosya için yapmanın eşdeğer bir yolu var mı?

Örneğin cat file(1|5).txtve sadece bu 2 yazdırmak?

Yanıtlar:


16

Standart dosya adı globbing desen eşleşmesi için bir basamak olduğunu [0-9]. Bu, tek bir rakamla eşleşir:

cat file[0-9].txt

Bunlardan yalnızca ikisini seçmek için:

cat file[25].txt

9'dan büyük sayılar için, küme ayracı genişletmesi yararlı olacaktır (ancak globbing desenleri ve küme ayracı genişletmeleri arasındaki fark için aşağıdaki nota bakın):

cat file{25..60}.txt

Yine, küme ayracı genişletme bireysel sayılara da izin verir:

cat file{12,45,900,xyz}.txt

(yukarıdaki örnekte, küme ayracı genişletmesinin aritmetik bir döngü içermediğini, ancak sağlanan dizelere göre yalnızca adlar oluşturduğunu unutmayın).

Yılında bash, ile extglobkabuk seçeneği (etkin shopt -s extglob), şu olacak ayrıca iş:

cat file@(12|45|490|foo).txt

@(...)Desen dahil herhangi birini maç olacak |-delimited desenleri.


Globbing olarak desen arasındaki fark [...]ve @(...)ve bağ açılımları, bir bağ genişleme olmasıdır komut satırında oluşturulan ve aslında geçerli dizinde varolan herhangi isimleri aynı olmayabilir. Bir dosya adı globbing kalıbı adlarla eşleşir, ancak kabuk tüm olası adlar yoksa şikayet etmez. Eğer hiçbir eşleştirme adından var da sürece, desen yorumlanmaksızın olmak kalacaktır nullglobkabuk seçeneği bu durumda Model çıkarıldığında,.

Misal:

touch file1

ls file[0-9]

Burada, yalnızca dosya listesi file1gösterilecektir.

İle ls file{0..9}, lsbulgu şikayet olmaz file0, file2vb

Aşağıdaki örnekte, ilk komut yalnızca verilen kalıpla eşleşen mevcut adlara dokunurken, ikinci satır zaten var olmayan dosyaları oluşturur:

touch file[0-9]

touch file{0..9}

@ thecarpy Üzgünüm, ama bu eşleşecek bir örnek değil mesela file45.txt. Köşeli ayraç ifadesi [...], normal ifadede olduğu gibi çalışır, ancak "içinde değil" demek !yerine kullanılır ^. Bir [...]desen her zaman tek bir karakterle eşleşir.
Kusalananda

Haklısın! BTW, benim {1,2}POSIX uyumlu da değil ... bugün birkaç yeni şey öğrendim!
thecarpy

2
Brace genişletmelerinin gerçek dosyalarla eşleşmesi gerekmemesi, (örneğin) geçirilecek kalıplar grepoluşturmak curl, geçirilecek URL'ler oluşturmak vb. İçin kullanıyorsanız ... ama aynı zamanda kafa karıştırıcı olabilir globlarla çalışmaya alışkın olan insanlara.
Kevin

@Kevin Correct. Bir küme ayracı genişletmesinin dosya adları hakkında olması gerekmez.
Kusalananda

7

Kullanımına sözdizimi file{1,2}için değerlendirecek olan file1ve file2.

$ ls
$ touch file{1,2,3,4,5,6,7,8,9}
$ ls
file1  file2  file3  file4  file5  file6  file7  file8  file9

Inian'ın da belirttiği gibi ... touch file{1..9}bu örnek durumda yapmak daha kolay olurdu ...

$ ls
$ touch file{1..9}
$ ls
file1  file2  file3  file4  file5  file6  file7  file8  file9

Ayrıca, aşağıdakiler gibi birden çok ifade kullanabilirsiniz:

$ ls
$ touch file{1..9}{a..z}
$ ls
file1a file1b file1c
[...]
file9x file9y file9z

Evet, yukarıdaki 234 ( 9kez 26) dosya oluşturacaktır.


1
Bu file{1,2} sözdizimi ayrıca dosyaları yeniden adlandırmak için de uygundur:mv some_very_long_filename.txt{,.bak}
Eric Duminil

6

Evet bashkabuğun içinde küme ayracı genişletme kullanabilirsiniz . Sadece birkaç dosya için file{1..2}ya da sadecefile{1,2}

Veya bazı durumlarda dosyaların bulunmadığından endişe ediyorsanız, basit bir döngü yapın,

for file in file{1..4}.txt; do
    [ -f "$file" ] || continue
    echo "$file" # Do other actions on file here
done

Ya da sadece birleştirme dosyaları üzerinde tek işleminiz ve hangi dosyaların herhangi bir zamanda bulunamayacağından emin değilseniz , sadece catonları ve hataları bastırın. /dev/nullDosya mevcut değilse, standart hatayı yeniden yönlendirmek hataları bastırır.

cat file{1,5}.txt 2>/dev/null

veya file[15]dosya bulunmazsa hatalardan şikayet etmeyen glob ifadesini kullanın .

cat file[15].txt

2
Hayır, orada olmayan dosyalar hakkında endişe yok, sadece sayısal olarak numaralandırılmış 2 dosyanın içeriğini göstermek istedim, ancak bu ardışık değil, bu yüzden file{1,5}virgül sözdizimi eksikti!
Joe Healey
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.