Küçük harf duyarsızlığını korurken ilk önce “ls” nin dotfiles göstermesini nasıl sağlayabilirim?


21

Bir dizinde aşağıdaki dosyaları oluşturun.

$ touch .a .b a b A B 你好嗎

Varsayılan lssiparişim, diğer dosyalarla iç içe geçerek öndeki noktaların varlığını yok sayar.

$ ls -Al
total 0
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 A
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 B
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:06 你好嗎

Ben yapabilirsiniz değiştirmek LC_COLLATE ilk dotfiles koymak.

$ LC_COLLATE=C ls -Al
total 0
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 A
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 B
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:06 你好嗎

Maalesef bu sıralama düzenini büyük / küçük harf duyarlı, yani Ave Bönce ave yapar b. Önce büyük / küçük harfe duyarsız kalırken ( Ave aönce Bve b) dotfiles yazdırmanın bir yolu var mı ?

Düzenleme: LC_COLLATE değiştirilmeye çalışılıyor

Şu ana kadarki cevapların hiçbiri lskolayca işlevselliğini tam olarak çoğaltmıyor . Muhtemelen, bazılarını bir fonksiyona sarabilirdim, fakat bunun (örneğin) bir argüman olmadan nasıl çalışılacağına ve bir dizini argüman olarak sunmaya ilişkin bazı ayrıntılı kodlar içermesi gerekir. Veya açık bir -dbayrakla nasıl başa çıkılacağı .

Alternatif olarak, belki daha iyi bir LC_COLLATEkullanımın olabileceğini düşündüm . Ancak, bu işi yapmak gibi görünmüyor. Şu anda kullanıyorum LC_COLLATE="en_AU.UTF-8". Kontrol ettim /usr/share/i18n/locales/en_AU(doğru dosya olup olmadığından emin değilim, ancak referans göremiyorum UTF-8); Aşağıdakileri buldum.

LC_COLLATE
copy "iso14651_t1"
END LC_COLLATE

/usr/share/i18n/locales/iso14651_t1içerir copy "iso14651_t1_common". Sonunda /usr/share/i18n/locales/iso14651_t1_commoniçerir

 <U002E> IGNORE;IGNORE;IGNORE;<U002E> # 47 .

Bu satırı sildim, koştum sudo locale-genve bilgisayarımı yeniden başlattım. Ne yazık ki, bu hiçbir şeyi değiştirmedi.

Yanıtlar:


11

OP düzenleme ile çok yakındı /usr/share/i18n/locales/iso14651_t1_common, ama püf noktası satırı silmek değil

<U002E> IGNORE;IGNORE;IGNORE;<U002E> # 47 .

ama onu değiştirmek yerine

<U002E> <RES-1>;IGNORE;IGNORE;<U002E> # 47 .

Bu neden çalışır

IGNOREİfadeleri tam durağı (aka dönem veya karakter belirtmek <U002E>alfabetik kelimeleri siparişi verirken) dikkate alınmayacaktır. Nokta dosyalarınızı önce gelmesi için, IGNOREdiğer tüm karakterlerden önce gelen bir harmanlama sembolüne geçin. Harmanlama sembolleri, gibi satırlarla tanımlanır.

collating-symbol <something-inside-angle-brackets>

ve çizginin görünümüne göre sıralanırlar.

<something-inside-angle-brackets>

Benim kopyamda iso14651_t1_common, ilk sıradaki harmanlama sembolü, <RES-1>3458 satırında görünür. Dosyalarınız farklıysa, önce hangi harmanlama sembolünü kullanın.

LC_COLLATE ile karakter siparişi hakkında detaylar

<U002E>Üç IGNOREdeyimi vardır, çünkü mektuplar bağlar halinde birkaç kez karşılaştırılabilir. Bunu anlamak için küçük harfleri ave büyük harfleri göz önünde bulundurun A(gerçekte dört kez karşılaştırılan bir karakter grubunun parçası olan):

<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A

Birden fazla karşılaştırma turuna sahip olmak, "a" ve "A" ile başlayan dosyaların birlikte gruplanmasına olanak tanır, çünkü her ikisi de <a>ilk geçişte olduğu gibi karşılaştırılır , bir sonraki mektubu sıralamayı belirler. Aşağıdaki harflerin tümü aynıysa (örn. a.txtVe A.txt), üçüncü geçiş a.txtilk olarak koyulur, çünkü küçük harfler için harmanlama simgesi <MIN>3467 satırında, büyük harfler için harmanlama sembolünden önce <CAP>(satır 3488) görünür .

Bu değişikliği uygulamak

Bir program her kullanımda harf siparişi verdiğinde, dönemin ilk önce gelmesini LC_COLLATEistiyorsanız, iso14651_t1_commonyukarıda açıklandığı şekilde değişiklik yapabilir ve konum dosyanızı yeniden oluşturabilirsiniz. Ancak bu değişikliği yalnızcals root erişimi için veya root erişimi olmadan yapmak istiyorsanız , orijinal yerel ayarları değiştirmeden önce başka bir dizine kopyalayabilirsiniz.

Ben ne yaptım

Benim varsayılan yerel ben kopyalanan böylece, tr olduğunu en_US, iso14651_t1ve iso14651_t1_commoniçin $HOME/path/to/new/locales. Ben Orada için yukarıda belirtilen değişiklik yaptık iso14651_t1_commonve adını en_USiçin en_DOTFILE. Sonra en_DOTFILE yerel ayarını ile derledim

localedef -i en_DOTFILE -f UTF-8 -vc $HOME/path/to/new/locales/en_DOTFILE.UTF-8

Varsayılan lssırayı değiştirmek için , adlı bir BASH betiği hazırlayın ls:

#!/bin/bash
LOCPATH=$HOME/path/to/new/locales LANG=en_DOTFILE.UTF-8 ls "$@"

yolunuzda daha önce görünen bir yere /usr/binkaydedin ve çalıştırılabilir duruma getirin chmod +x ls.


tabii ki, size dotfiles görmek -a veya -A eklemek gerekecek, ama her zaman onları görmek istiyorum sürece, değil senin BASH komut, komut satırında bunu mantıklı
BeanDip

Parlak! Teşekkürler, bu mükemmel! Sadece root tarafından sahip olunan dosyayı değiştirdim, bu yüzden betiğinizi test etmedim. Ancak, bence etrafınıza çift tırnak koymalısınız $@.
Sparhawk

iyi çağrı - çift tırnak eklendi
beandip

11

; Sen yerelin harmanlama sırası içermeyen hangi (yerine kabuk sıralama düzeni kullanabilirsiniz bashAT & T ksh, yash, tcshve zshbeklenen sonuçları verir, mkshve dashyapma. fishBir vaka duyarsız emri vermek gibi görünüyor ama ASCII olmayan vardır farklı sonuçlar verir karakter):

ls -dUl -- .* *

Bu, lslistelenecek dosyaların (ve dizinlerin) açık bir listesini verir ve lssıralamasını kaldırır ( -Ubir GNU uzantısıdır).

Kullanmakta olduğunuz kabuğa bağlı olarak birkaç uyarı vardır.

  • İle zsh, varsayılan nomatchseçenek, dizin hem gizli hem de gizli olmayan dosyalar içermiyorsa komutun başarısız olmasına neden olur; Bundan nomatchkaçınmak için devre dışı bırakabilirsiniz , ancak set -o cshnullglobbunun yerine daha iyisi olur (ve yalnızca hiçbiri (t)cshUnix'in kabuğundaki gibi ya da erken bir küre ile eşleşmiyorsa başarısız olma komutu ).
  • İle zsh, pdkshve onun türevi ve fish, .*'ın genişleme içermez .ve ..bu maçların yüzden ls -Al. Diğer kabukları ile birlikte .ve ..böylece dahildir ls -al. İkinci durumda, hariç tutmak için globbing modellerini değiştirmeniz gerekecektir .ve ..( ls -dUl -- ..?* .[!.]* *).
  • Bunun dışında fish, (t)cshveya zshherhangi bir genelleme düzeninin hiçbir şeyle eşleşmemesi lsdurumunda bir hata mesajı verilir; Eğer oluşturarak bu durumu önleyebilirsiniz nullglobseçeneği (içinde bashveya zshveya yönlendirerek en azından) stderriçin /dev/null( ls -dUl -- ..?* .[!.]* * 2>/dev/null). Eğer kullanırsanız nullglob, nedenleri potansiyel olarak-şaşırtıcı davranışları için dikkat (bkz Kabuk `yeme?` Karakterleri ). fishdavranacağını gibi basholan nomatch, bir uyarı mesajı eşleşme olan her topak için verilecektir zaman interaktif olması dışında.

( Tüm geri bildirimleriniz için Stéphane Chazelas'a teşekkürler !)


Yerelin harmanlama sırasını kullanarak tüm kabukların listeyi sıralamayacağını unutmayın. mkshve dashörneğin büyük / küçük harf duyarlılığı yapmaz.
Stéphane Chazelas

1
Not -U(sıralanmamış) bir GNU uzantısıdır. lsFreeBSD gibi diğer bazı uygulamaların bir var -Uama sıralanmamış listeleme için değil.
Stéphane Chazelas

GNU ile ls, daha --önce .*bu uygulamanın argümanlardan sonra seçenekleri kabul etmesinden önce ihtiyacınız var (POSIXLY_CORRECT çevrede değilse)
Stéphane Chazelas

Sinsi (+1)! Ancak, bunu her durumda, örneğin bir takma ad veya işlevde nasıl kolayca kullanabileceğimden emin değilim. Örneğin, lsbağımsız değişken olarak belirli bir dizini belirtmek isteyip istemediğim değişmeli .
Sparhawk

1
@PeterCordes [!.]doğru. Bkz pubs.opengroup.org/onlinepubs/9699919799/utilities/... . Bazı (çoğu?) Mermiler , olumsuzlanmış karakter sınıfı glob'larda ^eşanlamlı olarak izin verir !. Her durumda, ben .[!.] .??* *biraz daha anlaşılır olmayı tercih ediyorum.[!.]* ..?* *
jrw32982, 0

4

Sadece iki ayrı lskomut kullanabilirsiniz :

$ ls -dl ..?* .[^.]* 2>/dev/null ; ls -dl *
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 .a
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 .b
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 a
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 A
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 b
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 B
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 你好嗎

Şimdiye kadarki diğer cevapların aksine, bu yaklaşım önce .ve ..girişlerden kaçınan nokta dosyalarını , ardından kalan girişleri ls alfabetik sırayla görüntüler.

@StephenKitt cevap aynı sonucu elde etse de geliştirilebilir:

$ ls -dUl ..?* .[^.]* * 2>/dev/null

+1 de, ancak StephenKitt'in cevabına göre, bunu her durumda, yani takma ad veya fonksiyonda nasıl kullanabileceğime emin değilim. Örneğin, lsbağımsız değişken olarak belirli bir dizini belirtmek isteyip istemediğim değişmeli . (FWIW Ben zsh kullanıyorum, ancak sanırım bash insanlar için yararlı, sanırım.)
Sparhawk

-2

Ls komut seçenekleriyle oynayabilirsiniz . Bunu dene:

# ls -laXr

Nerede:

-l     use a long listing format
-a, --all
              do not ignore entries starting with .
-X     sort alphabetically by entry extension
-r, --reverse
              reverse order while sorting

Üzgünüm, bu istediğimi yapmıyor. -XBayrak sonra uzantısı tarafından sıralar .tamamen farklıdır. Ayrıca, dosyalar ters alfabetik sıradadır. Ayrıca, nokta dosyaları benim örneğim için ilk iken, her durumda işe yaramaz (örn. a.b c.d .a .c). Ayrıca, -ayerine kullandın -A.
Sparhawk
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.