Como mostrar apenas arquivos ocultos no Terminal?

154

Eu tenho um diretório que contém milhares de arquivos, alguns deles estão ocultos.

O comando ls -alista todos os arquivos, incluindo os ocultos, mas eu preciso apenas listar os arquivos ocultos.

Que comando devo usar?

nux
fonte
1
Um simples ls -ld .*ou ls -ald .*vai funcionar
John Strood

Respostas:

189

O comando :

ls -ld .?* 

Listará apenas arquivos ocultos.

Explicar :

 -l     use a long listing format

 -d, --directory
              list  directory entries instead of contents, and do not derefer‐
              ence symbolic links

.?* will only state hidden files 
nux
fonte
8
Você não precisa dos dois pontos de interrogação, o * o cobre (? Corresponde apenas a um caractere único, * corresponde a qualquer número deles).
Psusi
13
@psusi, acho que a intenção é excluir .e ..da partida. No entanto, também excluirá nomes de arquivos ocultos de caractere único (perfeitamente legais), como .a, .1etc. Talvez um glob melhor estendida seria .!(|.)dot ou seja literal seguido por qualquer coisa, exceto nada ou de outra (single) dot iels -d .!(|.)
steeldriver
@steeldriver, puro, o ?? A versão exclui "." e "..". Este parece ser o resultado de uma peculiaridade interessante: nenhum deles? nem * corresponderá a um ponto, mas o? deve corresponder a algo, caso contrário, o nome é ignorado.
Psusi
Para identificar diretórios e arquivos, adicione a opção F, ou seja, os nomes de diretório ls -ldF.? * Têm "/", como os arquivos de caracteres exibidos pela última vez.
RCF
1
Isso quase funciona, exceto que também lista uma pasta oculta como .vim, que eu considero não um arquivo aqui. Eu o modifico um pouco como ls -ldp.? * | grep -v / Apenas esta pasta lista arquivos ocultos não escondida
Fred Yang
31
ls -d .!(|.)

Faz exatamente o que o OP está procurando.

patrick
fonte
1
Como isso funciona?
precisa
lista diretório qualquer coisa com um. e não liste nada sem um é o que ele praticamente se traduz.
patrick
1
Entendo que em !(pattern-list), pattern-listhá uma lista de um ou mais padrões separados por a |, mas é confuso para mim que você não tenha nenhum padrão à esquerda de |. Você poderia me explicar essa sintaxe?
Carlos Mendoza
2
@CarlosMendoza que se tornaria o padrão vazio, então isso .não é seguido por (nada ou .), excluindo- .se e ...
muru 26/09/18
16

Se você quiser apenas os arquivos em seu diretório atual (sem recursão), poderá fazer

echo .[^.]*

Isso imprimirá os nomes de todos os arquivos cujo nome começa com a .e é seguido por um ou mais caracteres que não são pontos. Observe que isso falhará nos arquivos cujo nome começa com pontos consecutivos; portanto, por exemplo ....foo, não será mostrado.

Você também pode usar find:

find -mindepth 1 -prune -name '.*'

Os -mindepthgarante que não correspondem .e os -prunemeios que findnão vai descer para os subdiretórios.

terdon
fonte
15
ls -ad .*

trabalha para mim no Bash.

Marca
fonte
Shows .e ..em Bash
Penghe Geng 29/08/18
4

Usando finde awk,

find . -type f | awk -F"/" '$NF ~ /^\..*$/ {print $NF}'

Explicação:

find . -type f -> Liste todos os arquivos no diretório atual e seu caminho, como

./foo.html
./bar.html
./.foo1

awk -F"/" '$NF ~ /^\..*$/ {print $NF}'

/como o separador de campo awk verifica o último campo olhando com um ponto ou não. Se começar com um ponto, imprime o último campo dessa linha correspondente.

Avinash Raj
fonte
Você poderia apenas usar find -type f. Você não precisa definir explicitamente o caminho da pesquisa ou -name "*".
terdon
3

find geralmente é uma opção melhor para pesquisas complicadas do que usar globbing de nome.

find . -mindepth 1 -maxdepth 1 -name '.*'

ou

find . -mindepth 1 -maxdepth 1 -name '.*' -o -name '*~'

find . pesquisa no diretório atual

-mindepth 1exclui. e .. da lista

-maxdepth 1 limita a pesquisa ao diretório atual

-name '.*' encontre nomes de arquivos que começam com um ponto

-o ou

-name '*~' encontre nomes de arquivos que terminem com um til (geralmente, esses são arquivos de backup de programas de edição de texto)

No entanto, esta e todas as outras respostas perdem os arquivos que estão no .hiddenarquivo do diretório atual . Se você estiver escrevendo um script, essas linhas lerão o .hiddenarquivo e exibirão os nomes dos arquivos existentes.

if [[ -f .hidden]] # if '.hidden' exists and is a file
then
    while read filename # read file name from line
    do
        if [[ -e "$filename" ]] # if the read file name exists
        then
            echo "$filename" # print it
        fi
    done < .hidden # read from .hidden file
fi
Mark H
fonte
Qual é o .hiddenarquivo? Por que haveria um arquivo chamado .hiddenque contém os nomes dos arquivos? De qualquer forma, se houver, por que você faria algo tão complexo quando tudo o que seria necessário cat .hidden? Seu findcomando está correto (ish), mas o -name '*~'é irrelevante. Os arquivos que terminam em tildes são arquivos de backup, mas não ocultos de forma alguma.
terdon
@terdon O .hiddenarquivo é para arquivos e pastas que você deseja ocultar quando não pode alterar o nome do arquivo / pasta para começar com um ponto. Quanto aos arquivos que terminam em tildes, isso depende do sistema. ls -Birá ignorar esses arquivos, assim como a maioria dos exploradores de arquivos da GUI.
Mark H
cat .hiddenpode mostrar arquivos que não existem mais se esses arquivos foram excluídos ou movidos desde que foram adicionados ao .hiddenarquivo.
Mark H
Isso funciona bem.
Penghe Geng 29/08/18
2

Eu acho que você pode fazê-lo com o seguinte comando.

ls -a | grep "^\." | grep -v "^\.$" | grep -v "^\..$"

ls -a comando que você digitou, que mostra todos os arquivos e diretórios no diretório de trabalho atual.

grep "^\."comando que eu anexei, que filtra a saída para mostrar apenas arquivos ocultos (o nome começa com ".").

grep -v "^\.$" | grep -v "^\..$" comando que eu anexei, que filtra a saída para excluir., .. (Eles são o diretório atual e o pai).

Se alguns nomes de arquivos puderem ter mais de uma linha "\n", o exemplo acima pode estar incorreto.

Então, sugiro o seguinte comando para resolvê-lo.

find -maxdepth 1 -name ".[!.]*"
xiaodongjie
fonte
6
Você nuncals deve analisar a saída de .
Radu Rădeanu
@ RaduRădeanu Eu vi o seu comentário, é tão bom. Eu editei minha resposta novamente. Obrigado pelo seu comentário.
Xiaodongjie
2

O que mais você poderia ter feito, is ls .?*ou ls .!(|)isso mostrará tudo nos arquivos / diretórios ocultos do diretório atual na parte superior e nos outros arquivos / diretórios abaixo

por exemplo: do meu terminal

$ ls .?*       
.bash_history    .dmrc        .macromedia   .weather
.bash_logout     .gksu.lock   .profile      .wgetrc
.bash_profile    .bashrc.save .ICEauthority .toprc           .Xauthority
.bashrc          .lastdir     .viminfo      .xsession-errors
.bashrc~         .dircolors   .lynxrc       .vimrc           .xsession-errors.old

..:
Baron

.adobe:
Flash_Player

.aptitude:
cache  config

.cache:
compizconfig-1                              rhythmbox
dconf                                       shotwell

Agora observe nos resultados acima, ele mostra todos os arquivos / diretórios com seus subdiretórios e todos os arquivos ocultos logo abaixo.

[1:0:248][ebaron@37signals:pts/4][~/Desktop]
$ ls .!(|)
.bash_aliases  .bashrc1  .bashrc1~

..:
askapache-bash-profile.txt  examples.desktop             Public           top-1m.csv
backups             Firefox_wallpaper.png        PycharmProjects          top-1m.csv.zip
Desktop             java_error_in_PYCHARM_17581.log  Shotwell Import Log.txt  topsites.txt
Documents           Music                Templates            Videos
Downloads           Pictures                 texput.log           vmware

Desculpe, não posso comentar. para explicar a diferença aqui entre ls .?*e @ resposta cioby23 ls -d .[!.]* .??*E por isso que é realmente a impressão de arquivos ocultos duas vezes é porque literalmente você está perguntando duas vezes .??*, .?*, .[!.]*eles são a mesma coisa, então a adição de qualquer um deles com diferentes caracteres de comando irá imprimir duas vezes.

amrx
fonte
1

Você também pode usar:

ls -d .[!.]* .??*

Isso permitirá que você exiba arquivos ocultos normais e arquivos ocultos que começam com 2 ou 3 pontos, por exemplo: ..hidden_file

cioby23
fonte
1
Com isso, recebo todos os arquivos ocultos duas vezes.
19414 TuKsn
1

você pode usar o comando

ls -Ad .??*

Isso tem a vantagem de permitir a listagem de várias colunas, diferente da abordagem baseada em grep nas ls -a | grep "^\."soluções

Maythux
fonte
1

Todas as respostas até agora são baseadas no fato de que os arquivos (ou diretórios) cujos nomes começam com um ponto estão "ocultos". Eu vim com outra solução, que pode não ser tão eficiente, mas essa solução não assume nada sobre os nomes dos arquivos ocultos e, portanto, evita a listagem ..no resultado (assim como a resposta atualmente aceita).

O comando completo é:

ls -d $(echo -e "$(\ls)\n$(\ls -A)" | sort | uniq -u)

Explicação

O que isso faz é listar todos os arquivos (e diretórios) duas vezes,

echo -e "$(\ls)\n$(\ls -A)"

mas apenas mostrando arquivos ocultos uma vez -A.

Em seguida, a lista é classificada, o | sortque faz com que os arquivos regulares (não ocultos) sejam exibidos duas vezes e próximos um do outro.

Em seguida, remova todas as linhas que aparecem mais de uma vez | uniq -u, deixando apenas linhas exclusivas.

Finalmente, use lsnovamente para listar todos os arquivos com as opções personalizadas do usuário e sem listar o conteúdo dos diretórios na lista -d.

EDIT (Limitações):

Como muru apontou, esta solução não funcionará corretamente se houver arquivos com nomes como, escaped\ncharacter.txtporque echo -edividirá o nome do arquivo em duas linhas. Também não funcionará conforme o esperado se houver dois arquivos ocultos quase com o mesmo nome, exceto por um caractere especial, como .foo[tab].txte .foo[new-line].txtcomo ambos são impressos .foo?.txte seriam eliminados poruniq -u

alejandro
fonte
1
Eu acho que é praticamente a definição de arquivos ocultos. Até a origem desses arquivos ocultos é causada por um erro ao tratar .como o primeiro caractere.
muru 26/09/18
Menciono isso (como fato) no primeiro parágrafo. Ainda no entanto obtém um resultado diferente do que o atual aceita resposta
alejandro
Claro, exclui .., mas eu me pergunto o quão bem ele funciona com nomes de arquivos contendo caracteres especiais.
muru 26/09/18
Eu não sei exatamente o que você quer dizer com caracteres especiais, mas eu acho que não seria um problema, já que esta solução não assume nada sobre os nomes de arquivos
alejandro
Na verdade, você assume pelo menos uma coisa: os nomes de arquivos não têm novas linhas. Além disso: os nomes de arquivos não possuem sequências de escape neles que echo -eserão interpretadas. Além disso: lsnão irá alterar nomes de arquivos para que dois nomes de arquivos diferentes sejam exibidos da mesma forma (por exemplo, em algumas versões lsserão usados ?para caracteres especiais, portanto .foo\tbar( \t=> guia) e .foo\nbar( \n=> nova linha) aparecerão como foo?bar).
muru 26/09/18
1

Como alternativa, você também pode usar echo .*

por exemplo

user@linux:~$ echo .*
. .. .bash_aliases .bash_history .bash_logout .bashrc
user@linux:~$

Se você preferir em formato de lista longa, basta converter o espaço em branco em uma nova linha.

user@linux:~$ echo .* | tr ' ' '\n'
.
..
.bash_aliases
.bash_history
.bash_logout
.bashrc
user@linux:~$ 
Sabrina
fonte
0

Com o bash, definir a GLOBIGNOREvariável especial é algum valor não vazio é suficiente para fazê-lo ignorar .e ..ao expandir globs. Dos documentos do Bash :

A GLOBIGNOREvariável shell pode ser usada para restringir o conjunto de nomes de arquivos que correspondem a um padrão. Se GLOBIGNOREestiver definido, cada nome de arquivo correspondente que também corresponda a um dos padrões GLOBIGNOREé removido da lista de correspondências. Se a nocaseglobopção estiver configurada, a correspondência com os padrões GLOBIGNOREé executada sem considerar o caso. Os nomes de arquivos .e ..sempre são ignorados quando GLOBIGNOREdefinidos e não nulos. No entanto, a configuração GLOBIGNOREpara um valor não nulo tem o efeito de ativar a opção shell do dotglob, para que todos os outros nomes de arquivos que começam com ‘.'correspondam.

Se o definirmos .:.., ambos .e ..serão ignorados. Como configurá-lo para algo que não seja nulo também terá esse comportamento, é melhor configurá-lo para apenas.

Assim:

GLOBIGNORE=.
ls -d .*
muru
fonte