Comment afficher uniquement les fichiers cachés dans Terminal?

154

J'ai un répertoire qui contient des milliers de fichiers, certains sont cachés.

La commande ls -arépertorie tous les fichiers, y compris les fichiers cachés, mais il me suffit d’énumérer les fichiers cachés.

Quelle commande devrais-je utiliser?

nux
la source
1
Un simple ls -ld .*ou ls -ald .*va travailler
John Strood

Réponses:

189

La commande :

ls -ld .?* 

Ne listera que les fichiers cachés.

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 
nux
la source
8
Vous n'avez pas besoin des deux points d'interrogation, le * le couvre (? Ne correspond qu'à un seul caractère, * à un nombre quelconque d'entre eux).
Psusi
13
@ psusi, je pense que l'intention est d'exclure .et ..du match. Cependant, cela exclura également (parfaitement légal) les noms de fichiers cachés à un seul caractère tels que .a, .1etc. Peut-être un glob plus étendu serait .!(|.)-il un point littéral suivi de quoi que ce soit sauf rien ou un autre point (un seul), c.-à-dls -d .!(|.)
Steeldriver
@steeldriver, soigné, le ?? la version exclut "." et "..". Cela semble être le résultat d'une bizarrerie intéressante: ni? ni * ne correspondra à un point, mais le? doit correspondre à quelque chose sinon le nom est ignoré.
psusi
Pour identifier les répertoires et les fichiers, ajoutez l’option F, c’est-à-dire que les noms de répertoires ls -ldF.? * Ont "/", contrairement aux derniers fichiers de caractères affichés.
RCF
1
Cela fonctionne presque sauf qu'il répertorie également les dossiers cachés tels que .vim, que je ne considère pas comme un fichier ici. Je le modifie un peu comme ls -ldp.? * | grep -v / Cette liste ne contient que les fichiers cachés et non le dossier caché
Fred Yang le
31
ls -d .!(|.)

Fait exactement ce que cherche OP.

Patrick
la source
1
Comment ça marche?
SarcasticSully
Répertoire de liste quelque chose avec un. et ne rien énumérer sans un est ce que cela traduit assez bien.
Patrick
1
Je comprends que dans !(pattern-list), pattern-listest une liste d’un ou de plusieurs modèles séparés par un |, mais il m’embrouille de penser que vous n’avez pas de modèle à gauche de |. Pourriez-vous m'expliquer cette syntaxe?
Carlos Mendoza
2
@CarlosMendoza qui deviendrait le motif vide, c'est donc comme .ne pas suivi de (rien ou .), à l'exclusion de .lui-même et ...
Muru
16

Si vous voulez juste les fichiers dans votre répertoire courant (pas de récursion), vous pouvez le faire

echo .[^.]*

Cela affichera les noms de tous les fichiers dont le nom commence par un .et est suivi d'un ou de plusieurs caractères autres que des points. Notez que cela échouera pour les fichiers dont le nom commence par des points consécutifs, ainsi, par exemple ....foo, ne sera pas affiché.

Vous pouvez aussi utiliser find:

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

Le -mindepthgarantit que nous ne correspondons pas .et les -prunemoyens qui findne descendront pas dans les sous-répertoires.

terdon
la source
15
ls -ad .*

travaille pour moi à Bash.

marque
la source
Spectacles .et ..à Bash
Penghe Geng
4

L' utilisation findet awk,

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

Explication:

find . -type f -> Liste tous les fichiers du répertoire en cours avec son chemin comme,

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

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

/as séparateur de champs, awk vérifie si le dernier champ est marqué d’un point ou non. Si elle commence par un point, elle affiche le dernier champ de la ligne correspondante.

Avinash Raj
la source
Vous pouvez simplement utiliser find -type f. Vous n'avez pas besoin de définir explicitement le chemin de recherche ou -name "*".
terdon
3

find est généralement une meilleure option pour les recherches compliquées que l’utilisation de la suppression de nom.

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

ou

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

find . recherche dans le répertoire courant

-mindepth 1exclut. et .. de la liste

-maxdepth 1 limite la recherche au répertoire en cours

-name '.*' trouver des noms de fichiers commençant par un point

-o ou

-name '*~' rechercher des noms de fichiers qui se terminent par un tilde (généralement, il s'agit de fichiers de sauvegarde provenant de programmes d'édition de texte)

Toutefois, cela et toutes les autres réponses manquent des fichiers qui sont dans le .hiddenfichier du répertoire en cours. Si vous écrivez un script, ces lignes liront le .hiddenfichier et afficheront les noms de fichiers existants.

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
la source
Quel est le .hiddenfichier? Pourquoi y aurait-il un fichier appelé .hiddencontenant les noms de fichier? Quoi qu’il en soit, s’il ya lieu, pourquoi feriez-vous quelque chose de complexe alors que tout ce dont vous auriez besoin cat .hidden? Votre findcommande est correcte (ish) mais la -name '*~'est sans importance. Les fichiers qui se terminent par des tildes sont des fichiers de sauvegarde, mais ne sont en aucun cas cachés.
terdon
@terdon Le .hiddenfichier est destiné aux fichiers et dossiers que vous souhaitez masquer lorsque vous ne pouvez pas modifier le nom du fichier / dossier pour qu'il commence par un point. Quant aux fichiers qui se terminent par des tildes, cela dépend du système. ls -Bignorera ces fichiers, comme le feront la plupart des explorateurs de fichiers GUI.
Mark H
cat .hiddenpeut montrer des fichiers qui n'existent plus si ces fichiers ont été supprimés ou déplacés depuis leur ajout au .hiddenfichier.
Mark H
Ça marche bien.
Penghe Geng
2

Je pense que vous pouvez le faire avec la commande suivante.

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

ls -a La commande que vous avez entrée affiche tous les fichiers et répertoires du répertoire de travail en cours.

grep "^\."La commande que j’ai ajoutée, qui filtre la sortie en affiche uniquement les fichiers cachés (son nom commence par ".").

grep -v "^\.$" | grep -v "^\..$" commande que j’ai ajoutée, qui filtre la sortie à exclure., .. (Ce sont le répertoire courant et parent).

Si certains noms de fichiers peuvent avoir plus d'une ligne "\n", les exemples ci-dessus pourraient être incorrects.

Je suggère donc de suivre la commande pour résoudre ce problème.

find -maxdepth 1 -name ".[!.]*"
xiaodongjie
la source
6
Vous nels devriez jamais analyser le résultat de .
Radu Rădeanu
@ RaduRădeanu J'ai vu ton commentaire, c'est tellement bon. J'ai édité ma réponse à nouveau. Merci à votre commentaire.
xiaodongjie
2

Quoi d’autre que vous auriez pu faire, is ls .?*ou ls .!(|)qui vous montrera tout ce qui se trouve dans le répertoire en cours, les fichiers / répertoires cachés en haut et les autres fichiers / répertoires en dessous

par exemple: depuis mon 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

Maintenant, remarquez dans les résultats ci-dessus, il vous montre chaque fichier / répertoire avec son sous-répertoire et tous les fichiers cachés ci-dessous.

[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

Désolé, je ne peux pas commenter. pour expliquer la différence ici entre ls .?*et @ réponse cioby23 ls -d .[!.]* .??*Et pourquoi il est en fait l' impression de fichiers cachés est deux fois parce que littéralement vous demandez deux fois .??*, .?*, .[!.]*ils sont la même chose, afin d' ajouter l' un d'eux avec différents caractères de commande affiche deux fois.

Amrx
la source
1

Vous pouvez aussi utiliser:

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

Cela vous permettra d'afficher des fichiers cachés normaux et des fichiers cachés qui commencent par 2 ou 3 points, par exemple: ..hidden_file

cioby23
la source
1
Avec cela, je reçois deux fois tous les fichiers cachés.
Mars
1

vous pouvez utiliser la commande

ls -Ad .??*

Cela présente l’avantage de permettre une liste multi-colonnes, contrairement à l’approche basée sur grep dans les ls -a | grep "^\."solutions.

Maythux
la source
1

Jusqu'à présent, toutes les réponses reposent sur le fait que les fichiers (ou répertoires) dont les noms commencent par un point sont "cachés". Je suis venu avec une autre solution, qui pourrait ne pas être aussi efficace, mais cette solution ne suppose rien sur les noms des fichiers cachés, et évite donc de lister ..dans le résultat (comme le fait la réponse actuellement acceptée).

La commande complète est:

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

Explication

Cela permet de lister tous les fichiers (et répertoires) deux fois,

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

mais ne montrant qu'une fois les fichiers cachés -A.

Ensuite, la liste est triée, | sortce qui fait apparaître les fichiers normaux (non cachés) deux fois et les uns à côté des autres.

Ensuite, supprimez toutes les lignes qui apparaissent plusieurs fois | uniq -u, ne laissant que des lignes uniques.

Enfin, utilisez à lsnouveau pour répertorier tous les fichiers avec les options personnalisées de l'utilisateur et sans lister le contenu des répertoires de la liste -d.

EDIT (Limitations):

Comme le souligne muru, cette solution ne fonctionnera pas correctement s’il existe des fichiers portant des noms tels que escaped\ncharacter.txtcar echo -escindera le nom du fichier en deux lignes. Cela ne fonctionnera pas non plus comme prévu s'il y a deux fichiers cachés portant presque le même nom, à l'exception d'un caractère spécial, tel que .foo[tab].txtet .foo[new-line].txttels qu'ils sont imprimés tels quels .foo?.txtet seraient éliminés paruniq -u

Alejandro
la source
1
Je pense que c'est à peu près la définition des fichiers cachés. Même l'origine de ces fichiers cachés est due à un bogue dans le traitement .du premier caractère.
Muru
Je le mentionne (comme un fait) dans le premier paragraphe. Le résultat obtenu est toutefois différent de la réponse actuellement acceptée
alejandro le
Bien sûr, cela exclut .., mais je me demande si cela fonctionne bien avec les noms de fichiers contenant des caractères spéciaux.
Muru
Je ne sais pas exactement ce que vous entendez par caractères spéciaux, mais je penserais que cela ne poserait pas de problème, car cette solution ne suppose rien sur les noms de fichiers
alejandro
En fait, vous supposez au moins une chose: les noms de fichiers ne contiennent pas de nouvelles lignes. Aussi: les noms de fichiers n'ont pas de séquences d'échappement echo -einterprétables. Aussi: lsne modifiera pas les noms de fichiers de sorte que deux noms de fichiers différents soient affichés de la même manière (par exemple, certaines versions lsutiliseront ?des caractères spéciaux, ainsi .foo\tbar( \t=> tab) et .foo\nbar( \n=> nouvelle ligne) s'afficheront tous les deux comme foo?bar).
muru
1

Alternativement, vous pouvez également utiliser echo .*

par exemple

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

Si vous préférez le format de liste longue, convertissez simplement l'espace blanc en une nouvelle ligne.

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

Avec bash, définir la GLOBIGNOREvariable spéciale est une valeur non vide suffit à la faire ignorer .et ..à développer des globs. De la documentation Bash :

La GLOBIGNOREvariable shell peut être utilisée pour restreindre l’ensemble des noms de fichiers correspondant à un motif. Si GLOBIGNOREest défini, chaque nom de fichier correspondant qui correspond également à l'un des modèles GLOBIGNOREest supprimé de la liste des correspondances. Si l' nocasegloboption est définie, la correspondance avec les modèles GLOBIGNOREest effectuée sans tenir compte de la casse. Les noms de fichiers .et ..sont toujours ignorés lorsque GLOBIGNOREest défini et non nul. Toutefois, la définition GLOBIGNOREd'une valeur non nulle a pour effet d'activer l'option shell dotglob. Par conséquent, tous les autres noms de fichiers commençant par un ‘.'seront identiques.

Si nous le configurons à .:.., les deux .et ..seront ignorés. Ce comportement étant également défini sur une valeur non nulle, nous pouvons également le définir sur.

Alors:

GLOBIGNORE=.
ls -d .*
muru
la source