¿Cómo mostrar solo archivos ocultos en Terminal?


154

Tengo un directorio que contiene miles de archivos, algunos de ellos están ocultos.

El comando ls -aenumera todos los archivos, incluidos los ocultos, pero solo necesito enumerar los archivos ocultos.

¿Qué comando debo usar?


1
Un simple ls -ld .*o ls -ald .*funcionará
John Strood

Respuestas:


189

El comando :

ls -ld .?* 

Solo enumerará los archivos ocultos.

Explique :

 -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 

8
No necesita los dos signos de interrogación allí, el * lo cubre (? Solo coincide con un solo carácter, * coincide con cualquier número de ellos).
psusi

13
@psusi, creo que la intención es excluir .y ..del partido. Sin embargo, también excluirá nombres de archivo ocultos de un solo carácter (perfectamente legales) como .a, .1etc. Quizás un globo mejor extendido sería, por .!(|.)ejemplo, un punto literal seguido de cualquier cosa excepto nada u otro punto (único), es decirls -d .!(|.)
Steeldriver

@steeldriver, ordenado, el ?? la versión excluye "." y "..". Esto parece ser el resultado de una peculiaridad interesante: ¿ninguno? ni * coincidirá con un punto, pero el? debe coincidir con algo, de lo contrario se ignora el nombre.
psusi

Para identificar directorios y archivos, agregue la opción F, es decir, los nombres de directorio ls -ldF.? * Tienen "/" como los últimos archivos de caracteres mostrados no.
RCF

1
Esto casi funciona, excepto que también enumera carpetas ocultas como .vim, que considero que no es un archivo aquí. Lo modifico un poco como ls -ldp.? * | grep -v / Esto solo enumera los archivos ocultos no la carpeta oculta
Fred Yang

31
ls -d .!(|.)

Hace exactamente lo que OP está buscando.


1
¿Cómo funciona?
SarcasticSully

directorio de la lista cualquier cosa con un. y no enumeres nada sin uno es en lo que se traduce.
patrick

1
Entiendo que en !(pattern-list), pattern-listhay una lista de uno o más patrones separados por a |, pero me resulta confuso que no tenga ningún patrón a la izquierda |. ¿Podría explicarme esa sintaxis?
Carlos Mendoza

2
@CarlosMendoza que se convertiría en el patrón vacío, por lo que .no es seguido por (nada o .), excluyéndose .y ...
muru

16

Si solo desea los archivos en su directorio actual (sin recursividad), puede hacer

echo .[^.]*

Esto imprimirá los nombres de todos los archivos cuyo nombre comience con ay .siga uno o más caracteres que no sean puntos. Tenga en cuenta que esto fallará para los archivos cuyo nombre comience con puntos consecutivos, por lo que, por ejemplo ....foo, no se mostrará.

También puedes usar find:

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

Esto -mindepthasegura que no coincidamos .y los -prunemedios que findno descenderán a subdirectorios.



4

Usando findy awk,

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

Explicación:

find . -type f -> Lista todos los archivos en el directorio actual junto con su ruta como,

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

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

/como separador de campo awk comprueba el último campo que mira con un punto o no. Si comienza con un punto, imprime el último campo de esa línea correspondiente.


Podrías usarlo find -type f. No necesita establecer explícitamente la ruta de búsqueda o -name "*".
terdon

3

find Por lo general, es una mejor opción para búsquedas complicadas que usar el reconocimiento de nombres.

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

o

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

find . busca en el directorio actual

-mindepth 1excluye. y .. de la lista

-maxdepth 1 limita la búsqueda al directorio actual

-name '.*' buscar nombres de archivo que comienzan con un punto

-o o

-name '*~' buscar nombres de archivo que terminan con una tilde (generalmente, estos son archivos de respaldo de programas de edición de texto)

Sin embargo, esta y todas las otras respuestas pierden archivos que están en el .hiddenarchivo del directorio actual . Si está escribiendo una secuencia de comandos, estas líneas leerán el .hiddenarchivo y mostrarán los nombres de los 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

¿Cuál es el .hiddenarchivo? ¿Por qué habría un archivo llamado .hiddenque contiene los nombres de archivo? De todos modos, si hay uno, ¿por qué harías algo tan complejo cuando todo lo que necesitarías sería cat .hidden? Su findcomando es correcto (ish) pero -name '*~'es irrelevante. Los archivos que terminan en tildes son archivos de respaldo pero no están ocultos de ninguna manera.
terdon

@terdon El .hiddenarchivo es para archivos y carpetas que desea ocultar cuando no puede cambiar el nombre del archivo / carpeta para comenzar con un punto. En cuanto a los archivos que terminan en tildes, depende del sistema. ls -Bignorará dichos archivos, al igual que la mayoría de los exploradores de archivos GUI.
Mark H

cat .hiddenpuede mostrar archivos que ya no existen si esos archivos se eliminaron o movieron desde que se agregaron al .hiddenarchivo.
Mark H

Esto funciona bien
Penghe Geng

2

Creo que puedes hacerlo con el siguiente comando.

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

ls -a comando que ingresó, que muestra todos los archivos y directorios en el directorio de trabajo actual.

grep "^\."comando que agregué, que filtra la salida para mostrar solo archivos ocultos (su nombre comienza con ".").

grep -v "^\.$" | grep -v "^\..$" comando que agregué, que filtra la salida para excluir., .. (Son el directorio actual y principal).

Si algunos nombres de archivo pueden tener más de una línea "\n", el ejemplo anterior podría ser incorrecto.

Entonces sugiero seguir el comando para resolver el problema.

find -maxdepth 1 -name ".[!.]*"


@ RaduRădeanu Vi tu comentario, es tan bueno. Edité mi respuesta nuevamente. Gracias por tu comentario
xiaodongjie

2

Qué más podría haber hecho, is ls .?*o ls .!(|)eso le mostrará todo en el directorio actual archivos / directorios ocultos en la parte superior y otros archivos / directorios a continuación

por ejemplo: desde mi 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

Ahora observe en los resultados anteriores, le muestra cada archivo / directorio con su subdirección y cualquier archivo oculto justo debajo.

[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

Lo siento, no puedo comentar. para explicar la diferencia entre aquí ls .?*y la respuesta @ cioby23 ls -d .[!.]* .??*y por qué es en realidad la impresión de archivos ocultos en dos ocasiones se debe a que, literalmente, le está pidiendo dos veces .??*, .?*, .[!.]*que son la misma cosa, por lo que la adición de cualquiera de ellos con diferentes personajes comando imprimirá dos veces.


1

También puedes usar:

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

Esto le permitirá mostrar archivos ocultos normales y archivos ocultos que comienzan con 2 o 3 puntos, por ejemplo: ..hidden_file


1
Con esto obtengo todos los archivos ocultos dos veces.
TuKsn

1

puedes usar el comando

ls -Ad .??*

Esto tiene la ventaja de permitir el listado de varias columnas, a diferencia del enfoque basado en grep en las ls -a | grep "^\."soluciones


1

Todas las respuestas hasta ahora se basan en el hecho de que los archivos (o directorios) cuyos nombres comienzan con un punto están "ocultos". Se me ocurrió otra solución, que podría no ser tan eficiente, pero esta solución no asume nada sobre los nombres de los archivos ocultos y, por lo tanto, evita la inclusión ..en el resultado (como lo hace la respuesta actualmente aceptada).

El comando completo es:

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

Explicación

Lo que esto hace es enumerar todos los archivos (y directorios) dos veces,

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

pero solo muestra archivos ocultos una vez -A.

Luego se ordena la lista | sortque hace que los archivos regulares (no ocultos) aparezcan dos veces y uno al lado del otro.

Luego, elimine todas las líneas que aparecen más de una vez | uniq -u, dejando solo líneas únicas.

Finalmente, use lsnuevamente para enumerar todos los archivos con las opciones personalizadas del usuario y sin enumerar el contenido de los directorios en la lista -d.

EDITAR (Limitaciones):

Como señaló muru, esta solución no funcionará correctamente si hay archivos con nombres como escaped\ncharacter.txtporque echo -edividirá el nombre del archivo en dos líneas. Tampoco funcionará como se espera si hay dos archivos ocultos con casi el mismo nombre, excepto por un carácter especial, como .foo[tab].txty .foo[new-line].txtya que ambos se imprimen .foo?.txty serían eliminados poruniq -u


1
Creo que esa es más o menos la definición de archivos ocultos. Incluso el origen de estos archivos ocultos es un error al tratar con .el primer personaje.
muru

Menciono eso (como un hecho) en el primer párrafo. Sin embargo, aún obtiene un resultado diferente al de la respuesta aceptada actual
alejandro

Claro, excluye .., pero me pregunto qué tan bien funciona con nombres de archivo que contienen caracteres especiales.
muru

No sé exactamente qué quieres decir con caracteres especiales, pero creo que no representaría un problema, ya que esta solución no supone nada sobre los nombres de archivo
alejandro

En realidad, asumes al menos una cosa: los nombres de archivo no tienen líneas nuevas. Además: los nombres de archivo no tienen secuencias de escape en ellos que echo -einterpretarán. Además: lsno alterará los nombres de archivo para que dos nombres de archivo diferentes se muestren de la misma manera (por ejemplo, en algunas versiones lsse usarán ?caracteres especiales, por lo que .foo\tbar( \t=> tabulación) y .foo\nbar( \n=> nueva línea) aparecerán como foo?bar).
muru

1

Alternativamente, también puedes usar echo .*

p.ej

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

Si lo prefiere en formato de lista larga, simplemente convierta el espacio en blanco en una nueva línea.

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

0

Con bash, establecer la GLOBIGNOREvariable especial es que un valor no vacío es suficiente para ignorarlo .y ..al expandir los globos. De los documentos de Bash :

La GLOBIGNOREvariable de shell puede usarse para restringir el conjunto de nombres de archivo que coinciden con un patrón. Si GLOBIGNOREestá configurado, cada nombre de archivo coincidente que también coincida con uno de los patrones GLOBIGNOREse eliminará de la lista de coincidencias. Si nocaseglobse establece la opción, la comparación con los patrones GLOBIGNOREse realiza sin tener en cuenta el caso. Los nombres de archivo .y ..siempre se ignoran cuando GLOBIGNOREse establece y no es nulo. Sin embargo, establecer GLOBIGNOREun valor no nulo tiene el efecto de habilitar la opción de shell dotglob, por lo que todos los demás nombres de archivos que comienzan con ‘.'coincidirán.

Si lo ponemos al .:..tanto .y ..se ignorará. Dado que establecerlo en algo que no sea nulo también obtendrá este comportamiento, también podríamos configurarlo en solo.

Entonces:

GLOBIGNORE=.
ls -d .*
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.