Eu tenho um diretório no qual gostaria de listar todo o conteúdo (arquivos e subdiretórios) sem mostrar os links simbólicos. Estou usando utilitários GNU no Linux. A ls
versão é 8.13.
Exemplo:
Lista completa de diretórios:
~/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
O que eu gostaria de receber
~/test$ ls -somthing (or bash hack)
total 12
dir1 dir2 dir3 file1 file2
NOTA: Minha principal motivação é fazer um grep recursivo (GNU grep 2.10) sem seguir os links simbólicos.
grep
(veja o último parágrafo).grep -H
, se você o tiver (consulteman grep
), ou façagrep 'pat' '{}' /dev/null ';'
-o pensar que existem vários arquivos, se não o tiver.+
falha em atender a esse requisito no caso degenerado em que existe apenas um arquivo ou um arquivo no final.Ou, mais simples:
Explicação
ls -l
significa listar em formato longo . Quando você faz isso, a primeira sequência de caracteres fornece informações sobre cada arquivo. O primeiro caractere indica que tipo de arquivo é. Se é um link simbólico, entãol
é o primeiro caractere.grep -v ^l
significa filtrar (-v
) as linhas que começam com (^
) anl
.fonte
for i in
-l
emls
. Então, isso não iria funcionar como esperado:ls | grep -v ^l
find
, consulte unix.stackexchange.com/questions/321697A partir da versão 2.12, a
-r
opção GNU grep não desrefere links simbólicos, a menos que você os especifique manualmente:fonte
-R, -r, --recursive Read all files under each directory, recursively; this is equivalent to the -d recurse option.
em 2.10No zsh, isso seria fácil graças aos qualificadores da glob :
O padrão
**/
percorre subdiretórios recursivamente. O qualificador global.
restringe a correspondência aos arquivos regulares.Sem o zsh, use
find
(veja a resposta de Michael Horner ). E nesse caso em particular, o GNU grep pode fazer o que você deseja (é exatamente o quegrep -r
faz) - mas somente desde a versão 2.12, as versões anteriores seguiram links simbólicos.fonte
Você pode usar
$LS_COLORS
para fazer isso. Se sua versão dols
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:Então agora eu vou fazer:
E os nulos também estão lá ...
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 atribuirdircolors
padrões configurados no ambiente atual :Sua saída no meu diretório pessoal é assim:
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 porls --color=always
essa configuração - apenas o que você vê aqui.ls
insere seu terminal padrão como este:... onde os valores padrão para
$lc
(à esquerda do código) ,$rc
(à direita do código) e$rs
(redefinir) são:...respectivamente.
${type_code}
é usado para substituir os váriosfi
(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 pequenoIFS=:
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
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 einfo 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 usareicat -A
, porém, sem ele, seria o mesmo que no último exemplo: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:Meus resultados após a execução se parecem com ...
Usando algum comando como o que eu faço acima:
... (onde
fc1
efc2
são os tipos de arquivos listados depoisset --
no subshell) deve servir para remover com segurança quaisquer combinações de tipos de arquivos que você possa desejar dals
saída, independentemente de qualquer caractere que os nomes de arquivos possam conter.fonte
lc
,nc
, etc, são?ls
odi=
valor. Você precisaria adicionardi=:
ao var para anular isso - e para todos os outros. É o que quero dizer com API - você endereça cada tipo de arquivo, mas é necessário endereçar a mesma interface em todos os casos. Portanto, definirln
uma maneira e ignorar osdi
padrões não funcionará. Existem muitos padrões compilados também ... Hmm. Sua pergunta sobrelc
andnc
and stuff é válida - completamente - eu já fiz isso outro dia. Vou ligar, acho.dircolors
. Ele lê um arquivo de configuração e gera umeval
valor var amigável para o shell . É bem fácil - mas também são poucas as linhas lá em cima. De qualquer forma, se você quiser usá-dircolors
lo, salve dois arquivos diferentes e invoque-o dessa maneira. Além disso, mostrei a você outro dia como fazer as duas coisas ao mesmo tempo com\0
delimitadores NUL como parte de cada sequência 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
A resposta acima leva ao seguinte:
Curiosamente, deixar o 1 fora do comando ls ainda fornece uma lista.
fonte
grep -i
? Não é como se/
pudesse ser maiúsculo ou minúsculo.ls
assume o formato de coluna noe quando a saída não é um terminal (é um tubo aqui).Tente este:
fonte
a -> b
. Ele também falhará nos nomes de arquivos com novas linhas e outras estranhezas. Leia isto para saber por que analisar ls é uma má ideia.ls
é um aliasls -l
, e isso retorna colunas antes do nome do arquivo, ou não é, e isso não faz nada de especial nos links simbólicos.ls
analisa a si próprio. todos analisamosls
toda vez que imprimimos em um terminal - há uma API . Publiquei uma resposta demonstrando algo parecido aqui - mas você pode fazer muito mais. Eu mostrei a você outro dia - você mesmo tinha nomes de arquivo delimitados por nulo.ls
não vai comer seus filhos nem nada - é apenas um programa. Se você não explicar, serão necessárias várias centenas para explicar e várias centenas para explicar por que as várias centenas de linhas às quais você acabou de vincular estão erradas. E além disso - são apenas duas linhas:LS_COLORS='lc=:rc=:ec=:ln=\n\n\0HERE_THERE_BE_A_LINK>>\0:' \ ls -1 --color=always | cat
Tente este comando:
ls -p | grep -v @
fonte
find -type f
-p
just adiciona uma barra aos diretórios, você está procurando-F
ii) suafind
alternativa não listará os diretórios e iii) Teste suas respostas antes de postar.