Sayısal olarak sıralanmış dosyaları listeleme


122

Ben gelen dosyaların bir grup var log1için log164.

Bir UNIX terminalindeki dizini (sıralanmıştır) LIST yapmaya çalışıyorum, ancak sıralama işlevleri sadece şu şekilde format sağlıyor:

home:logs Home$ ls -1 | sort
log1.gz
log10.gz
log100.gz
log101.gz
log102.gz
log103.gz
log104.gz
log105.gz
log106.gz
...etc

İstediğim şey

home:logs Home$ ls -1 | sort
log1.gz
log2.gz
log3.gz
log4.gz
log5.gz
log6.gz
log7.gz
...{more here}
log99.gz
log100.gz
log101.gz
log102.gz
...etc

Bunu yapmak için ne kullanabileceğim konusunda herhangi bir öneriniz var mı?


8
Bu kesinlikle bir programlama sorusudur ve cevap, kabuk kabuğu programlama dilini içerdiği için taşınmayı hak etmemektedir !!!
tchrist

Eğer onlar İsminin önceden biliyorsanız log1.gzaracılığıyla log164.gz, o zaman bile ne gerekiyor ls -1onlara?
12'de

1
@ruakh ls -1 sonuçları, daha sonra

3
@Rabiani: Ne yaptığını biliyorum ls -1: dosya adlarını listeler. Dosya adlarını zaten bildiğiniz için, neye ihtiyacınız olduğunu anlamadım. Eğer Kevin'ın cevabını kabul ettim çünkü Ama şimdi biliyorum: etmedi olması gerekiyor. Bu daha mantıklı. :-)
ruakh

Yanıtlar:


40

bash'nin diş telleri, {}sırayla numaralandırır:

for file in log{1..164}.gz; do
    process "$file"
done

266

Neden lsbu özel durum için yerleşik bir özellik kullanmıyorsunuz?

-v natural sort of (version) numbers within text

Örneğin ls -1v log*


Müthiş bir çözüm, keşke bir sortdosya
dizinden

23
BSD / OSX üzerinde bu seçenek başka bir şeydir: -v - Force unedited printing of non-graphic characters.
kenorb

Maalesef -v seçeneği AIX'te (6.1) kullanılamaz
bouvierr

6
Bu en iyi cevap olmalı.
32r34wgf3e

1
MacOS için bu işe yarayacak, belirtildiği gibi bir seçenek bulamadık,ls | sort -n
Ricky Levi

47

GNU l'lerle (yani Linux, Cygwin veya GNU'ları özel olarak yüklenmiş diğer sistemlerde):

ls -v

Zsh içinde:

echo *(n)

Diğer kabuklarda:

echo log?.gz log??.gz log???.gz

Değiştir echotarafından printf '%s\n'ayrı bir satırda her dosya adını istiyorum.

Dosya meta verilerini de ( ls -l) lsistiyorsanız ve GNU'nuz yoksa, sözlük sırasına göre görmek istediğiniz her dosya adı veya dosya adı grubu için ayrı ayrı arama yapmanız gerekir .

ls -ld log?.gz; ls -ld log??.gz; ls -ld log???.gz

Bu zorluklardan kaçınmak için, dosya adlarınızda, sözlükbilgisi türünün insan dostu ( log001.gz, vb.) Olması için yeterince baştaki sıfır kullanın .


29

Çözüm ls -1v, bu özel durumda kesinlikle en güzel olmasına rağmen, sortgirişiniz gelmediği zaman da çalıştığı için, asıl soruda olduğu gibi çalışmanın da iyi olduğunu düşünüyorum ls. Bu durumda kullanabilirsiniz:

ls -1 | sort -n -k1.4

-nSeçenek sayısal sıralamak için sıralama söyler ve -k 1.4son kadar 4. karakterden başlayarak (bu durumda bütün dosya adıdır) ilk alana sıralama anahtarını ayarlar.


Benim durumumda, ls -1 | sort -n -k1.4çalışmıyor. İlk başta 4 karaktere kadar sıralanmamış olanlar verir, ardından 4. karakterden sonra sıralanır Onun ls -1 |sort | sort -n -k1.4yerine kullandım ve mükemmel çalıştı.
Prabhu

3
@Prabhu yerine, yapabilirdi sort -k1.1,1.3 -k1.4n. sortuygulamaların kararlı olması gerekmediğinden , yaklaşımınız tüm uygulamalarla çalışmayacaktır. Ayrıca -VGNU ve FreeBSD opsiyonlarına bakınız sort.
Stéphane Chazelas

21

GNU sort(Linux'ta olduğu gibi), numarasız sayılardaki sayıları istediğiniz gibi yorumlayan bir "sürüm sıralama" moduna sahiptir:

Kimden man 1 sort:

    -V, --version-sort
           natural sort of (version) numbers within text

(Boş test dosyaları oluşturma Listeye:
touch log1.gz log2.gz log3.gz log99.gz log100.gz log101.gz log102.gz)

Örnek olay, -Vseçenek (veya --version-sort) ekleyerek :

ls -1 log*.gz | sort -V
log1.gz
log2.gz
log3.gz
log99.gz
log100.gz
log101.gz
log102.gz


3

Solaris versiyonum desteklemiyor ls -v(grrr). Ve yukarıda verilen sıralama çözümü 1) dosya adındaki basamakların konumu hakkında bilgi gerektirir ve 2) çok parçalı sürüm numaraları gibi şeyleri işlemez.

Aşağıdaki yaklaşım Solaris uyumludur, rakam konumlarının bilinmesini gerektirmez ve sürüm numaralarını 2, 3 veya 4 bileşenle kullanır (örneğin: a-1.2, foo-5.6.7, bar_baz_9.10.11.12). Ayrıca, sort -fbüyük ve küçük harfleri birlikte katlamak için kullanılır ve dosyalarla karıştırılan dizinleri düzgün biçimde işler:

ls -d | sort -f -t . -k 1,1 -k 2,2n -k 3,3n -k 4,4n

Bu sürümün ilk bileşeni tek bir rakamla sınırladığını unutmayın.

Hedef işletim sisteminiz destekliyorsa ls -v, bu kesinlikle üstün bir çözümdür.


1

Perl çözümü:

ls log*.gz | perl -ne 'sub getnum{ $_[0] =~ /log(\d+)\.gz/; $1 }; push @A, $_; END{ print sort { getnum $a <=> $b } @A}'

1
$ ls
log101.gz  log102.gz  log103.gz  log104.gz  log105.gz  log106.gz  log10.gz  log1.gz
$ ls | sort -t . -n -k1.4
log1.gz
log10.gz
log101.gz
log102.gz
log103.gz
log104.gz
log105.gz
log106.gz

1
-t .Burada gereksiz olduğunu.
Stéphane Chazelas

0

Bu benim için çalıştı.

Dosyalarım var 1.jpg 2.jpg ... 18.jpg

$ echo *.jpg | tr -s ' ' '\n' | sort -n

sortlsyazdırılamayan renk karakterleri nedeniyle çıktılarla karıştırılıyor . Bunu denersen:

ls -1 --color=none *.jpg | sort -n

mükemmel çalışacak.

sort-iseçeneği ile yazdırılamayan karakterleri yok sayabilir, ancak yine de çalışmıyor ve nedenini bilmiyorum.

Ama her zaman böyle renk soyun ve sortişe yarar:

ls -1 --color=always *.jpg | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | sort -n

Umarım bir gün sortbunun için bir seçenek olacaktır.

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.