Puedes usar $LS_COLORS
para hacer esto. Si su versión de ls
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:
for f in 9 8 7 6 5 4 3 2 1
do touch "${f}file" &&
ln -s ./"${f}file" ./"${f}filelink"
done
Entonces ahora haré:
LS_COLORS='lc=:rc=:ec=:ln=\n\n\0HERE_THERE_BE_A_LINK>>\0:' \
ls -1 --color=always | cat
###OUTPUT###
1file
HERE_THERE_BE_A_LINK>>1filelink@
2file
HERE_THERE_BE_A_LINK>>2filelink@
3file
...
HERE_THERE_BE_A_LINK>>8filelink@
9file
...
Y los nulos también están ahí ...
LS_COLORS='lc=:rc=:ec=:ln=\n\n\0HERE_THERE_BE_A_LINK>>\0:' \
ls -1 --color=always | sed -n l
1file$
$
$
\000HERE_THERE_BE_A_LINK>>\0001filelink@$
2file$
$
$
\000HERE_THERE_BE_A_LINK>>\0002filelink@$
3file$
...
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 asignar dircolors
valores predeterminados configurados para el entorno actual :
LS_COLORS='rs=:no=//:lc=:rc=:ec=//:'$(
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//:"
done) ls -l --color=always | cat
Su salida en mi directorio de inicio se ve así:
total 884
///-rw-r--r-- 1 mikeserv mikeserv 793 Jul 9 11:23 /fi//1/
//drwxr-xr-x 1 mikeserv mikeserv 574 Jun 24 16:50 /di//Desktop//
//-rw-r--r-- 1 mikeserv mikeserv 166 Jul 4 23:02 /fi//Terminology.log/
//-rw-r--r-- 1 mikeserv mikeserv 0 Jul 6 11:24 /fi//new
file/
//lrwxrwxrwx 1 mikeserv mikeserv 10 Jul 11 04:18 /ln//new
file
link/ -> /fi//./new
file/
//-rwxr-xr-x 1 mikeserv mikeserv 190 Jun 22 11:26 /ex//script.sh/*
//-rw-r--r-- 1 mikeserv mikeserv 433568 Jun 22 17:10 /fi//shot-2014-06-22_17-10-16.jpg/
//-rw-r--r-- 1 mikeserv mikeserv 68 Jun 17 19:59 /fi//target.txt/
También puede ejecutar eso cat -A
y la única diferencia que encontrará es que verá $
nuevas líneas: no se introducen caracteres no imprimibles ls --color=always
con esta configuración, solo lo que ve aquí.
ls
inserta sus escapes de terminal predeterminados de esta manera:
${lc}${type_code}${rc}FILENAME${lc}${rs}${rc}
... donde los valores predeterminados para $lc
(izquierda del código) , $rc
(derecha del código) y $rs
(restablecer) son:
\033 - ESCAPE
m - END ESCAPE
0 - reset
...respectivamente. ${type_code}
se utiliza para reemplazar los diversos fi
(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ño IFS=:
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
printf %s "$LS_COLORS"
rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:\
so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:\
or=40;31;01:su=37;41:sg=30;43:ca=30;41:\
tw=30;42:ow=34;42:st=37;44:ex=01;32:\
*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:...
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 y info 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 lo cat -A
usaré, sin embargo, sin él, se vería igual que el último ejemplo:
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
total 884$
^@//^@//-rw-r--r-- 1 mikeserv mikeserv 793 Jul 9 11:23 /fi//^@1^@//$
^@//drwxr-xr-x 1 mikeserv mikeserv 574 Jun 24 16:50 /di//^@Desktop^@///$
^@//-rw-r--r-- 1 mikeserv mikeserv 166 Jul 4 23:02 /fi//^@Terminology.log^@//$
^@//-rw-r--r-- 1 mikeserv mikeserv 0 Jul 6 11:24 /fi//^@new$
file^@//$
^@//lrwxrwxrwx 1 mikeserv mikeserv 10 Jul 11 04:18 /ln//^@new$
file$
link^@// -> /fi//^@./new$
file^@//$
^@//-rwxr-xr-x 1 mikeserv mikeserv 190 Jun 22 11:26 /ex//^@script.sh^@//*$
^@//-rw-r--r-- 1 mikeserv mikeserv 433568 Jun 22 17:10 /fi//^@shot-2014-06-22_17-10-16.jpg^@//$
^@//-rw-r--r-- 1 mikeserv mikeserv 68 Jun 17 19:59 /fi//^@target.txt^@//$
Y para eliminar de manera confiable todos los enlaces simbólicos de una -l
lista única como esta, puede hacer un cambio simple:
LS_COLORS='rs=:no=//:lc=:rc=:ec=/ :'$(
set -- di fi mh pi so do bd cd or su sg ca tw ow st ex
for fc do printf %s "$fc=$fc/:"
done)ln=///: ls -l --color=always | sed ':ln
\|///|{N;\|\n//|!bln};s|.*//||'
Mis resultados después de correr se parecen a ...
total 884
-rw-r--r-- 1 mikeserv mikeserv 793 Jul 9 11:23 fi/1/
drwxr-xr-x 1 mikeserv mikeserv 574 Jun 24 16:50 di/Desktop/ /
-rw-r--r-- 1 mikeserv mikeserv 166 Jul 4 23:02 fi/Terminology.log/
-rw-r--r-- 1 mikeserv mikeserv 0 Jul 6 11:24 fi/new
file/
-rwxr-xr-x 1 mikeserv mikeserv 190 Jun 22 11:26 ex/script.sh/ *
-rw-r--r-- 1 mikeserv mikeserv 433568 Jun 22 17:10 fi/shot-2014-06-22_17-10-16.jpg/
-rw-r--r-- 1 mikeserv mikeserv 68 Jun 17 19:59 fi/target.txt/
Usando algún comando como el que hago arriba:
LSCOLORS=...$(...)fc1=///:fc2=///: ls ... | sed ...
... (donde fc1
y fc2
son los tipos de archivo enumerados después set --
en la subshell) debería servir para eliminar de forma confiable cualquier combinación de tipos de archivo que desee de la ls
salida, independientemente de los caracteres que puedan contener los nombres de archivo.