Tengo un directorio en el que me gustaría enumerar todo el contenido (archivos y subdirectorios) sin mostrar los enlaces simbólicos. Estoy usando utilidades GNU en Linux. La ls
versión es 8.13.
Ejemplo:
Listado completo del directorio:
~/test$ ls -Gg
total 12
drwxrwxr-x 2 4096 Jul 9 10:29 dir1
drwxrwxr-x 2 4096 Jul 9 10:29 dir2
drwxrwxr-x 2 4096 Jul 9 10:29 dir3
-rw-rw-r-- 1 0 Jul 9 10:29 file1
-rw-rw-r-- 1 0 Jul 9 10:29 file2
lrwxrwxrwx 1 5 Jul 9 10:29 link1 -> link1
lrwxrwxrwx 1 5 Jul 9 10:30 link2 -> link2
Lo que me gustaría obtener
~/test$ ls -somthing (or bash hack)
total 12
dir1 dir2 dir3 file1 file2
NOTA: Mi motivación principal es hacer un grep recursivo (GNU grep 2.10) sin seguir los enlaces simbólicos.
grep
(ver el último párrafo).grep -H
, si lo tiene (verman grep
), o de lo contrariogrep 'pat' '{}' /dev/null ';'
para engañarlo haciéndole creer que hay varios archivos si no lo tiene.+
no cumple ese requisito en el caso degenerado donde solo queda un archivo o un archivo al final.O, más simple:
Explicación
ls -l
significa listar en forma larga . Cuando hace esto, la primera cadena de caracteres proporciona información sobre cada archivo. El primer carácter indica de qué tipo es cada archivo. Si es un enlace simbólico, entoncesl
es el primer carácter.grep -v ^l
significa filtrar (-v
) las líneas que comienzan con (^
) anl
.fuente
for i in
-l
enls
. Entonces esto no funcionaría como se esperaba:ls | grep -v ^l
find
, vea unix.stackexchange.com/questions/321697Desde la versión 2.12 en adelante, la
-r
opción para GNU grep no desreferencia los enlaces simbólicos a menos que los especifique a mano:fuente
-R, -r, --recursive Read all files under each directory, recursively; this is equivalent to the -d recurse option.
en 2.10En zsh, esto sería fácil gracias a los calificadores glob :
El patrón
**/
atraviesa subdirectorios de forma recursiva. El calificador glob.
restringe la coincidencia con los archivos normales.Sin zsh, use
find
(vea la respuesta de Michael Horner ). Y en este caso particular, GNU grep puede hacer lo que quiera (es exactamente lo quegrep -r
hace), pero solo desde la versión 2.12, las versiones anteriores siguieron enlaces simbólicos.fuente
Puedes usar
$LS_COLORS
para hacer esto. Si su versión dels
admite la especificación de los colores usando esa variable, puede definir la salida por tipo de archivo. Es un comportamiento incorporado y muy configurable. Así que creé algunos archivos para demostrar esto como:Entonces ahora haré:
Y los nulos también están ahí ...
Puede especificar todos o cualquier tipo de archivo. Sin embargo, hacerlo solo para un solo tipo de archivo podría no ser lo que desea, ya que
ls
ha incorporado algunos valores de compilación predeterminados para escapes de terminal. Sería mucho mejor abordar la API como una interfaz única. Aquí hay un pequeño medio simple de analizar y asignardircolors
valores predeterminados configurados para el entorno actual :Su salida en mi directorio de inicio se ve así:
También puede ejecutar eso
cat -A
y la única diferencia que encontrará es que verá$
nuevas líneas: no se introducen caracteres no imprimiblesls --color=always
con esta configuración, solo lo que ve aquí.ls
inserta sus escapes de terminal predeterminados de esta manera:... donde los valores predeterminados para
$lc
(izquierda del código) ,$rc
(derecha del código) y$rs
(restablecer) son:...respectivamente.
${type_code}
se utiliza para reemplazar los diversosfi
(archivo normal - desarmado predeterminado) ,di
(directorio) ,ln
(enlace) y cualquier otro tipo de archivo que conozca. También hay$no
(normal) que también está desarmado por defecto y que aquí está representado por//
al principio de cada línea. Mi pequeñoIFS=:
bloque simple funciona simplemente insertando el nombre de cada configurable también como su propio valor y agregando una barra oblicua o dos, aunque los\0
bytes NUL también lo harían.Por defecto
ls
, también insertará uno$rs
inmediatamente anterior a su primera salida$lc
, pero esto no se representa con precisión aquí. En este caso, he especificado$ec
(código final) que significa en$rs
todos los casos; cuando se especifica, no obtiene un extra$rs
entre$no
y${type_code}
como lo haría de otra manera, solo se presenta inmediatamente después de un nombre de archivo y una vez al comienzo de la salida - Como puede ver en la barra extra en la cabecera de la línea uno.Aquí hay un fragmento de mi propio
$LS_COLORS
Y, en verdad, mi pequeño truco de shell es probablemente demasiado complicado: hay una interfaz ampliamente disponible para asignar estos valores. Pruebe
dircolors -p
en su cli yinfo dircolors
para obtener más información al respecto.Puede envolver los nombres de archivo en cadenas arbitrarias. Puede comentarlos si lo desea. Puede especificar comportamientos similares basados solo en la extensión del archivo. Realmente no hay mucho que no puedas especificar de esa manera.
Ahora tampoco estoy inventando todo esto: me enteré después de tropezar con el código fuente por accidente.
Con esta configuración particular
ls
emitirá:$no
- una vez por registro al comienzo de cada registro${type_code}
- una vez que precede inmediatamente a cada nombre de archivo para incluir una abreviatura del tipo de archivo y siempre aparece en la misma línea y 7 campos delimitados por espacios en blanco después$no
o inmediatamente después de->
denotar el objetivo de un enlace simbólico.$ec
- una vez inmediatamente antes de la primera línea y luego solo una vez inmediatamente después de cada nombre de archivo.Todos los demás valores están vacíos.
Lo que sigue es un delimitado por nulo
ls
, y esta vez locat -A
usaré, sin embargo, sin él, se vería igual que el último ejemplo:Y para eliminar de manera confiable todos los enlaces simbólicos de una
-l
lista única como esta, puede hacer un cambio simple:Mis resultados después de correr se parecen a ...
Usando algún comando como el que hago arriba:
... (donde
fc1
yfc2
son los tipos de archivo enumerados despuésset --
en la subshell) debería servir para eliminar de forma confiable cualquier combinación de tipos de archivo que desee de lals
salida, independientemente de los caracteres que puedan contener los nombres de archivo.fuente
lc
,nc
, etc, son?ls
'sdi=
valor. Tendría que agregardi=:
a la var para anular eso, y para todos los demás. Es lo que quiero decir con la API: usted aborda cada tipo de archivo, pero debe abordar la interfaz de la misma manera en todos los casos. Por lo tanto, establecerln
un camino e ignorar losdi
valores predeterminados no funcionará. También hay muchos valores predeterminados compilados ... Hmm. Su preguntando porlc
ync
y esas cosas es válida - por completo - Ya lo hizo el otro día, sin embargo. Lo vincularé, creo.dircolors
. Lee un archivo de configuración y genera uneval
valor var amigable con el shell . Es bastante fácil, pero también lo son las pocas líneas allí arriba. De todos modos, si quisieras usarlodircolors
, solo guarda dos archivos diferentes e invoca de esa manera. Además, le mostré el otro día cómo hacer ambas cosas a la vez con\0
delimitadores NUL como parte de cada secuencia de escape.LS_COLORS='rs=:no=\0//:lc=:rc=:ec=\0//:'$( set -- di fi ln mh pi so do bd cd or su sg ca tw ow st ex; for fc do printf %s "$fc=/$fc//\0:"; done) ls -l --color=always | cat -A
La respuesta anterior lleva a lo siguiente:
Curiosamente, dejar el 1 fuera del comando ls todavía da una lista.
fuente
grep -i
? No es como si/
fuera mayúscula o minúscula.ls
el valor predeterminado es un formato de columna noe cuando la salida no es una terminal (aquí es una tubería).Prueba este:
fuente
a -> b
. También fallará en los nombres de archivo con nuevas líneas y otras extrañezas. Lea esto para saber por qué analizar ls es una mala idea.ls
tiene un aliasls -l
, y esto devuelve columnas antes del nombre del archivo, o no lo es, y esto no hace nada especial sobre los enlaces simbólicos.ls
analiza a sí mismo. todos analizamosls
cada vez que imprimimos en una terminal; hay una API . Publiqué una respuesta que demuestra algo así aquí, pero puedes hacer mucho más. Te lo mostré el otro día: tenías nombres de archivo delimitados por nulos.ls
no se va a comer a tus hijos ni nada, es solo un programa. Si no explicas entonces se llevará varios cientos de explicarlo y varios cientos más para explicar por qué los varios cientos de líneas que acaba de vincular a están equivocados. Y además - esto es sólo dos líneas:LS_COLORS='lc=:rc=:ec=:ln=\n\n\0HERE_THERE_BE_A_LINK>>\0:' \ ls -1 --color=always | cat
Prueba este comando:
ls -p | grep -v @
fuente
find -type f
-p
Simplemente agrega una barra diagonal a los directorios, está buscando-F
ii) sufind
alternativa no incluirá una lista de directorios y iii) Pruebe sus respuestas antes de publicar.