Você pode usar $LS_COLORS
para fazer isso. Se sua versão do ls
suporta a especificação das cores usando essa variável, é possível definir a saída por tipo de arquivo. É um comportamento embutido e muito configurável. Então, eu criei alguns arquivos para demonstrar isso como:
for f in 9 8 7 6 5 4 3 2 1
do touch "${f}file" &&
ln -s ./"${f}file" ./"${f}filelink"
done
Então agora eu vou fazer:
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
...
E os nulos também estão lá ...
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$
...
Você pode especificar para todos ou quaisquer tipos de arquivos. Fazer isso apenas para um único tipo de arquivo pode não o desejar, pois ls
incorporou alguns valores de compilação padrão para escapes de terminal. Você faria muito melhor abordar a API como uma única interface. Aqui está um pequeno meio simples de analisar e atribuir dircolors
padrões configurados no ambiente atual :
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
Sua saída no meu diretório pessoal é assim:
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/
Você também pode executá-lo cat -A
e a única diferença que encontrará é que verá $
novas linhas - não há caracteres imprimíveis introduzidos por ls --color=always
essa configuração - apenas o que você vê aqui.
ls
insere seu terminal padrão como este:
${lc}${type_code}${rc}FILENAME${lc}${rs}${rc}
... onde os valores padrão para $lc
(à esquerda do código) , $rc
(à direita do código) e $rs
(redefinir) são:
\033 - ESCAPE
m - END ESCAPE
0 - reset
...respectivamente. ${type_code}
é usado para substituir os vários fi
(arquivo regular - padrão não definido) , di
(diretório) , ln
(link) e todos os outros tipos de arquivos que eu conheço. Também há $no
(normal) que também é, por padrão, desativado e que é representado aqui pelo //
no início de cada linha. Meu pequeno IFS=:
bloco simples funciona apenas inserindo o nome de cada configurável também como seu próprio valor e adicionando uma barra ou duas - embora \0
NUL bytes funcionassem também.
Por padrão ls
, também será inserido um $rs
imediatamente anterior à sua primeira saída $lc
- mas isso não é representado com precisão aqui. Nesse caso, eu especifiquei $ec
(código final) que representa $rs
todos os casos - quando especificado, você não recebe um extra $rs
entre $no
e ${type_code}
como faria de outra maneira - ele só é apresentado imediatamente após um nome de arquivo e uma vez no início da saída - como você pode ver na barra extra no início da linha um.
Aqui está um trecho do meu próprio $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:...
E, na verdade, meu pequeno shell hack é provavelmente muito complicado - há uma interface amplamente disponível para atribuir esses valores. Tente dircolors -p
em sua cli e info dircolors
para mais informações sobre isso.
Você pode agrupar os nomes de arquivos em cadeias arbitrárias. Você pode comentá-los, se desejar. Você pode especificar comportamentos semelhantes com base apenas na extensão do arquivo. Não há realmente muita coisa que você não possa especificar dessa maneira.
Agora também não estou inventando tudo isso - aprendi sobre isso depois de tropeçar no código fonte por acidente.
Com esta configuração particular ls
emitirá:
$no
- uma vez por registro no início de cada registro
${type_code}
- uma vez imediatamente antes de cada nome de arquivo para incluir uma abreviação do tipo de arquivo e sempre ocorrendo na mesma linha que os campos delimitados por 7 espaços em branco, após $no
ou imediatamente após a ->
indicação do destino de um link simbólico.
$ec
- uma vez imediatamente antes da primeira linha e depois apenas uma vez imediatamente após cada nome de arquivo.
Todos os outros valores estão vazios.
O que se segue é um nulo-delimitado ls
, e desta vez usarei cat -A
, porém, sem ele, seria o mesmo que no último exemplo:
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^@//$
E, para remover de forma confiável todos os links simbólicos de uma -l
listagem ong como esta, faça uma alteração simples:
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|.*//||'
Meus resultados após a execução se parecem com ...
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 algum comando como o que eu faço acima:
LSCOLORS=...$(...)fc1=///:fc2=///: ls ... | sed ...
... (onde fc1
e fc2
são os tipos de arquivos listados depois set --
no subshell) deve servir para remover com segurança quaisquer combinações de tipos de arquivos que você possa desejar da ls
saída, independentemente de qualquer caractere que os nomes de arquivos possam conter.