¿Cómo hago primero para ordenar los caracteres de subrayado?

20

Me gusta poder nombrar archivos y directorios con un prefijo de subrayado si es algo que quiero mantener separado de otros archivos y directorios en el mismo nivel. En Windows y Mac, por ejemplo, el prefijo de un archivo con un guión bajo lo ordena al principio, delante de los archivos que comienzan con un carácter alfanumérico.

Se descubrió que Google tiene que ver con LC_COLLATE y mi ubicación actual (en_US). Eso está bien, aunque realmente no entiendo por qué en_US no se ordena como se esperaba.

Basado en la configuración regional del sitio de demostración de ICU Collate en en_US_POSIX ciertamente parece tener el orden de clasificación que estoy buscando (debe editar los datos de muestra y agregar algunos guiones bajos para probarlo). Pero realmente no veo cómo aplicar esto en mi shell de Linux.

Idealmente, me gustaría poder configurar algo en mi configuración bash para que ls siempre clasifique los guiones bajos primero. ¿Cómo haría para hacer esto?

Tom Auger
fuente
No puedo reproducir usando ICU Collate con valores predeterminados o con en_US_POSIX.txt a través de "Obtener reglas para la configuración regional". ¿Puedes explicar la configuración que usaste?
Mikel
Pregunta similar askubuntu.com/questions/47702/…
Mikel
@Mikel utilizando el enlace que proporcioné anteriormente, agregue algunos guiones bajos a los datos de prueba y luego envíelos para ver los resultados del tipo.
Tom Auger
Eso es exactamente lo que hice, y las cadenas que comienzan con guiones bajos se ordenan en el medio en lugar de al principio, como si los guiones bajos no estuvieran allí.
Mikel
1
Una pregunta relacionada, que trata de cambiar realmente la definición del orden de clasificación, es unix.stackexchange.com/questions/421908 .
JdeBP

Respuestas:

5

Si no puede lsordenar de la manera que desea, pruebe la expansión de shell.

Puede usar patrones de nombre de archivo para ejecutar lscon una lista de archivos que el shell ya ordenó, omitiendo el método que lsusa.

ls -lf _* [!_]*

Asumiendo que tienes los archivos

_a a _b b _c c

esto es como correr

ls -lf _a _b _c a b c

Explicación:

_* es un patrón de shell que coincide con cualquier nombre de archivo que comienza con un guión bajo, expandido en orden alfabético.

[!_]*coincide con cualquier nombre de archivo que no comience con un guión bajo, expandido en orden alfabético.

-fle dice lsa no ordenar, porque el shell ya lo hizo.

Más información: expansión de nombre de archivo bash

Si hay directorios en el directorio actual, querrá ejecutar el comando de esta manera para evitar la inclusión de archivos en los directorios:

ls -lfd _* [!_]*
Mikel
fuente
77
Por cierto, DOS / Windows / OSX realmente no ponen guiones bajos antes que nada: clasifican entre mayúsculas y minúsculas con el guión bajo antes de las letras, pero algunos otros caracteres de puntuación van antes o después del guión bajo. Usar _para hacer que los archivos aparezcan primero es un truco específico del sistema operativo; y la versión unix de este truco es comenzar el nombre del archivo con una letra mayúscula: la convención predeterminada de Unix es usar solo letras minúsculas en los nombres de los archivos.
Gilles 'SO- deja de ser malvado'
44
O ceros; por ej 00README.
mattdm
1
@Gilles +1 para la mejor práctica de Unix de usar mayúsculas en archivos importantes para que sean los primeros. Al final del día, si esa es la convención, probablemente sea mejor que simplemente adopte eso, en lugar de intentar forzar a Unix a que se comporte como lo hacen otros sistemas operativos para que pueda usar las convenciones que se desarrollaron para Mac o Windows. Gracias por el gran consejo.
Tom Auger
1
@TomAuger -fle dice que lsno haga su propia clasificación, por lo que muestra sus argumentos en el orden en que se pasan. El resultado de cada expansión de comodín de shell _*y [!_]*es una lista ordenada lexicográficamente.
Gilles 'SO- deja de ser malvado'
1
@TomAuger Los argumentos a lsse ordenan (en dos grupos: los que comienzan con _los otros) cuando son generados por el shell. Corre echo ls -lf _* [!_]*para ver qué pasa. La -fbandera le dice que lsno haga ninguna clasificación.
Gilles 'SO- deja de ser malvado'
16

Si no le importa mezclar minúsculas y mayúsculas, establezca su configuración regional en C, que toma los caracteres en su orden numérico. _cae entre mayúsculas y minúsculas.

$ LC_COLLATE=C ls    
BAR  FOO  _score  _under  hello  world
$ LC_COLLATE=en_US ls                    
BAR  FOO  hello  _score  _under  world

La configuración regional LC_MESSAGES(idioma de los mensajes de error), LC_CTYPE(juegos de caracteres) y LC_TIME(formato de fecha y hora) son muy útiles. LC_COLLATEy LC_NUMERICgeneralmente son más problemáticos de lo que valen, no recomiendo configurarlos. La ordenación lexicográfica adecuada es más complicada de lo que LC_COLLATEse supone que debe especificar, y puede causar todo tipo de comportamientos extraños cuando usa rangos de caracteres en expresiones regulares. LC_NUMERICes principalmente cosmético, excepto cuando algo sale terriblemente mal porque algún programa produjo un número con un separador decimal distinto de ..

Gilles 'SO- deja de ser malvado'
fuente
+1 Muy interesante. Entonces, utilizando este formulario, ¿está configurando temporalmente la variable de entorno LC_COLLATE solo para esa instancia de ls? ¿Está bien?
Tom Auger
1
¿Alguna forma de hacer que los guiones bajos aparezcan ANTES de las letras mayúsculas?
Tom Auger
1
@TomAuger Sí, VAR=value cmdconjuntos VARa valuesólo en el entorno de cmdy no toca el valor (o la ausencia de valor) en el shell en el que se ejecuta. Para que el guión bajo aparezca antes que en mayúscula, deberá definir su propia configuración regional. Esto es posible, pero difícil de usar, porque al menos en Linux, la biblioteca estándar solo busca definiciones de configuración regional /usr/lib/locale: no hay ninguna ~/.localevariable de entorno en la que pueda establecer su en_tomconfiguración.
Gilles 'SO- deja de ser malvado'
@TomAuger Si se trata solo del lscomando, sigue la sugerencia de Mikel .
Gilles 'SO- deja de ser malvado'
2

Desafortunadamente, Linux usa glibc para su información local, no ICU, por lo que no hay forma de aplicarlo directamente a Linux sin gastar mucho esfuerzo, ya sea readaptando ICU en glibc o complementando la información local en glibc.

Ignacio Vazquez-Abrams
fuente
-4

Agregar el -finterruptor (sin ordenar) hizo que se mostrara así para mí.

man ls

[root@dusknoir ~/java/test]# ls -fl
total 0
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 _1
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 _2
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 _3
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 1
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 2
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 3
Tim
fuente
66
Solo porque así es como se almacenan en el sistema de archivos.
Ignacio Vazquez-Abrams
3
Lo siento, pero esta respuesta es completamente incorrecta. Prueba: touch 3 1 _1 _3 2 _2 && ls -flsalidas2 . 1 3 _2 _3 .. _1
Marco