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.