Eu gosto de poder nomear arquivos e diretórios com um prefixo de sublinhado, se for algo que eu quero manter separado de outros arquivos e diretórios no mesmo nível. No Windows e Mac, por exemplo, o prefixo de um arquivo com um sublinhado o classifica para o topo, na frente de arquivos que começam com um caractere alfanumérico.
Meu google descobriu que tem a ver com LC_COLLATE e meu local atual (en_US). Tudo bem, embora eu realmente não entenda por que o en_US não é o esperado.
Com base na configuração do site de demonstração ICU Collate , o locale para en_US_POSIX certamente parece ter a ordem de classificação que estou procurando (você deve editar os dados da amostra e adicionar alguns sublinhados para testá-los). Mas eu realmente não vejo como aplicar isso no meu shell Linux.
Idealmente, eu gostaria de poder configurar algo na minha configuração do bash para que ele sempre classifique os sublinhados primeiro. Como eu faria isso?
Respostas:
Se você não conseguir
ls
classificar da maneira que quiser, tente a expansão do shell.Você pode usar padrões de nome de arquivo para executar
ls
com uma lista de arquivos que o shell já classificou, ignorando o métodols
usado.Supondo que você tenha os arquivos
isso é como correr
Explicação:
_*
é um padrão de shell que corresponde a qualquer nome de arquivo que comece com um sublinhado, expandido em ordem alfabética.[!_]*
corresponde a qualquer nome de arquivo que não comece com um sublinhado, expandido em ordem alfabética.-f
dizls
para não classificar, porque o shell já fez.Mais informações: expansão do nome do arquivo bash
Se houver diretórios no diretório atual, você desejará executar o comando como este para evitar ls listando arquivos nos diretórios:
fonte
_
para fazer com que os arquivos apareçam primeiro é uma invasão específica do sistema operacional; e a versão unix desse hack é iniciar o nome do arquivo com uma letra maiúscula: a convenção unix padrão é usar apenas letras minúsculas nos nomes dos arquivos.00README
.-f
dizls
para não fazer sua própria classificação; portanto, ele exibe seus argumentos na ordem em que são passados. O resultado de cada expansão do curinga do shell_*
e[!_]*
é uma lista classificada lexicograficamente.ls
são classificados (em dois grupos: os que começam com_
e os outros) quando são gerados pelo shell. Corraecho ls -lf _* [!_]*
para ver o que acontece. A-f
bandeira dizls
para não fazer nenhuma classificação.Se você não deseja misturar letras minúsculas e maiúsculas, defina seu código do idioma como
C
, que recebe os caracteres na ordem numérica._
cai entre maiúsculas e minúsculas.As configurações de localidade
LC_MESSAGES
(idioma das mensagens de erro),LC_CTYPE
(conjuntos de caracteres) eLC_TIME
(formato de data e hora) são muito úteis.LC_COLLATE
eLC_NUMERIC
geralmente são mais problemáticos do que valem, não recomendo configurá-los. A classificação lexicográfica adequada é mais complicada do queLC_COLLATE
deveria ser especificada e pode causar todo tipo de comportamento estranho quando você usa intervalos de caracteres em expressões regulares.LC_NUMERIC
é principalmente cosmético, exceto quando algo dá terrivelmente errado, porque algum programa produziu um número com um separador decimal diferente de.
.fonte
VAR=value cmd
conjuntosVAR
paravalue
apenas no ambiente decmd
e não toca o valor (ou ausência de valor) no shell onde você executá-lo. Para fazer o sublinhado aparecer antes de maiúsculas, você precisa definir suas próprias configurações de localidade. Isso é possível, mas difícil de usar, porque pelo menos no Linux, a biblioteca padrão procura apenas definições de localidade/usr/lib/locale
- não há~/.locale
variável de ambiente ou onde você possaen_tom
definir sua configuração.ls
comando, siga a sugestão de Mikel .Infelizmente, o Linux usa glibc para suas informações de localidade, não para ICU; portanto, não há como aplicá-lo diretamente no Linux sem gastar muito esforço, atualizando a ICU na glibc ou suplementando as informações de localidade na glibc.
fonte
A adição do
-f
interruptor (sem classificação) fez com que ele fosse mostrado dessa maneira para mim.man ls
fonte
touch 3 1 _1 _3 2 _2 && ls -fl
saídas2 . 1 3 _2 _3 .. _1