Liste seulement les fichiers normaux (mais pas les répertoires) dans le répertoire courant

126

Je peux utiliser ls -ld */pour lister toutes les entrées du répertoire dans le répertoire actuel. Existe-t-il un moyen aussi simple de répertorier tous les fichiers normaux du répertoire en cours? Je sais que je peux utiliser trouver

find . -maxdepth 1 -type f

ou stat

stat -c "%F %n" * | grep "regular file" | cut -d' ' -f 3-

mais ceux-ci ne me paraissent pas trop élégants. Existe-t-il un moyen simple et sympa de ne répertorier que les fichiers normaux (les périphériques, les pipes, etc., ça ne me dérange pas) mais pas les sous-répertoires du répertoire courant? La liste des liens symboliques serait également un avantage, mais ce n’est pas une nécessité.

daniel kullmann
la source
5
Qu'entendez-vous par "trop ​​élégant"? Autant que je sache, la findcommande est la meilleure façon de faire ce que vous voulez. Pour certaines autres options fiables, vous devriez vous pencher sur les commandes spécifiques au shell (et celles-ci sont tout sauf portables)!
Rahmu
@rahmu J'étais pour quelque chose de similaire à ls -d */, qui est court, facile à taper et facile à comprendre. Je suis donc assez content de la réponse d'Ulrich Dangel, même si je n'utilise pas zsh.
daniel kullmann

Réponses:

32

Avec zshet Glob Qualifiers, vous pouvez facilement l'exprimer directement, par exemple:

echo *(.)

renverra uniquement la liste des fichiers normaux ou une erreur en fonction de votre configuration.

Pour les non-annuaires:

echo *(^/)

(comprendra des liens symboliques (y compris vers des répertoires), des tubes nommés, des périphériques, des sockets, des portes ...)

echo *(-.)

pour des fichiers normaux et des liens symboliques vers des fichiers normaux.

echo *(-^/)

pour les non-répertoires et pas de liens symboliques vers les répertoires non plus.

En outre, voir le Dqualificatif de globbing si vous souhaitez inclure D fichiers ot (fichiers cachés), comme *(D-.).

Ulrich Dangel
la source
170
ls -p | grep -v / 

Cette commande répertorie tous les fichiers non cachés qui ne sont pas des répertoires (fichiers normaux, liens, fichiers de périphérique , etc.). Pour inclure également les fichiers cachés, ajoutez l’ -Aoption àls

Cela suppose qu'aucun fichier ne contient de caractères de nouvelle ligne. Ajouter une -qoption pour lstransformer tous les caractères non imprimables, y compris newline ?, en garantissant qu’ils soient sur une seule ligne et donc appropriés pour être alimentés par un utilitaire basé sur une ligne comme greppour l’impression sur un terminal.

Athul Biju
la source
14
+1, c'est une bonne réponse. Abaisser le vote d'un nouvel utilisateur sans commentaire me choque beaucoup, surtout quand une réponse satisfaisante est fournie. Le seul cas où je peux voir où cela ne fonctionnera pas correctement est s'il y a une nouvelle ligne dans un nom de fichier. Le fait de conserver également les couleurs serait un ajout intéressant là où il est pris en charge. Pour GNU, vous pouvez ajouter --color=alwaysà lsOSX -G.
Graeme
Bonjour, la commande que vous avez donnée est excellente et aide certainement, mais je me demandais s’il était possible d’utiliser la commande ci-dessus et de modifier l’autorisation de fichier en même temps? J'ai essayé d'ajouter sudo chmod 777à la fin, et on m'a donné des erreurs ... Toute aide est grandement appréciée
dissidia
3
Si vous souhaitez également exclure les liens symboliques pointant vers des répertoires, faites-le ls -pL | grep -v /. Les -Lliens symboliques de déréférences ajoutés .
Matthias Braun
1
Si vous souhaitez également utiliser un filtre générique, faites-le ls -pdL something* | grep -v /. L' -doption ajoutée répertorie les répertoires eux-mêmes, pas leur contenu, afin qu'ils soient correctement exclus.
Rockallite
Et si vous vouliez récupérer tous les fichiers sans dossier, supprimez simplement le -v
jasonleonhard 10/09
23

Pour lister uniquement les fichiers normaux:

ls -al | grep '^-'

Avec des liens symboliques (vers tout type de fichier) inclus:

ls -al | grep '^[-l]'

Où le premier caractère de la liste décrit le type de fichier, ce -qui signifie qu'il s'agit d'un fichier normal, car le lien symbolique l'est l.

Debian / Ubuntu

Imprimer les noms de tous les fichiers correspondants (y compris les liens):

run-parts --list --regex . .

Avec des chemins absolus:

run-parts --list --regex . "$PWD"

Imprimez les noms de tous les fichiers de /etcce début pet finissez par d:

run-parts --list --regex '^p.*d$' /etc
Kenorb
la source
15

lsn’a pas le choix, mais l’un des avantages de unix et linux est que les pipelines longs et inélégants peuvent facilement être transformés en script shell, en fonction ou en alias. et ceux-ci peuvent, à leur tour, être utilisés dans les pipelines comme tout autre programme.

(REMARQUE: il existe des problèmes de portée avec les fonctions et les alias. Les scripts sont disponibles pour tout exécutable capable de les lire et de les exécuter. Les alias et les fonctions ne sont disponibles que dans le shell actuel - bien que les fichiers .profile / .bashrc etc. puissent être redéfinis. En outre, un script peut être écrit dans n’importe quelle langue - y compris bash / sh, awk, perl, python, et d’autres - quelle que soit celle qui convient le mieux à votre travail ou que vous connaissez le mieux)

par exemple

alias lsf='find . -maxdepth 1 -type f -print0 | xargs -0r ls'

J'ai ajouté xargs pour pouvoir utiliser toutes les lsoptions habituelles , par exemplelsf -lrS

Parce qu'il utilise find, tous les fichiers de points normalement masqués seront affichés et tous les noms de fichiers porteront le préfixe ./, c'est à peu près la seule différence que vous remarquerez.

Vous pouvez exclure les fichiers de points avec, ! -iname '.*'mais vous devez alors avoir deux versions de l’alias - une qui affiche les fichiers de points et une autre qui ne l’a pas.

alias lsf2='find . -maxdepth 1 -type f -a ! -iname '\''.*'\'' -print0 | xargs -0r ls'

Alternativement, si lsfétait un script plutôt qu'un alias, vous pouvez analyser les options (peut-être avec getopts ou / usr / bin / getopt ou similaire), et exclure les fichiers de points sauf s'ils -aétaient présents.

cas
la source
-nameest suffisant, vous n’avez pas besoin -iname.
Totor
8
bash-4.2$ ls -F | grep -v '[/@=|]$' | more

L'option -F de ls ajoute * aux exécutables, / aux répertoires, @ aux liens symboliques, = aux sockets et | aux FIFO. Vous pouvez ensuite utiliser grep pour exclure les caractères de fichier non standard de la sortie et vous disposez des fichiers. Cela fonctionnera dans n’importe quel shell, pas seulement zsh.

Les faiblesses sont:

  1. Tout fichier dont le nom se termine par @, =ou |seront exclus (mais vous ne devriez pas avoir vraiment des fichiers avec ces personnages au nom de toute façon)
  2. Cela n'exclut pas les fichiers de périphérique ou certains types de fichiers exotiques sur certains systèmes, tels que les portes.
  3. Un astérisque sera ajouté à tout fichier exécutable. Cela pourrait être traité en passant par sed pour supprimer tous les caractères '*' de la sortie.
  4. Cela ne fonctionne pas correctement s'il existe des noms de fichiers contenant des caractères de nouvelle ligne.
Kurtm
la source
Sur le système que j'écris ceci sur 10% des dossiers ont des noms contenant =, @ou |caractères. =est courant dans maildir ou dans les noms de fichiers comportant une partie encodée en base64 ou avec une citation imprimable @dans les définitions de paramètres régionaux, pour les adresses électroniques, etc. Il est rare qu’ils apparaissent à la fin du nom de fichier. (seulement 31 sur 2,2 millions sur ce système par exemple)
Stéphane Chazelas
3

Le manuel indiquait que l'option 'f' ne visait que le fichier normal, pas les pipes, les sockets ou les périphériques block / char, ce qui signifie que vous faites déjà le bon travail.

   -type c
          File is of type c:

          b      block (buffered) special

          c      character (unbuffered) special

          d      directory

          p      named pipe (FIFO)

          f      regular file

          l      symbolic link; this is never true if the -L option or the
                 -follow option is in effect, unless the symbolic link  is
                 broken.  If you want to search for symbolic links when -L
                 is in effect, use -xtype.

          s      socket

          D      door (Solaris)
Marguerite
la source
0

Ce n'est pas particulièrement court, mais vous pouvez le transformer en script ou en alias si vous devez l'appeler rapidement. À l'aide de la commande ls en tant que tableau d'entrée, appelez ls -ld sur chaque entrée acheminée vers grep pour exclure les répertoires dont le résultat est envoyé à null. Si l'opération réussit, indiquez à nouveau l'entrée d'origine:

for list in `ls` ; do ls -ld $list | grep -v ^d > /dev/null && echo $list ; done ;

Vous pouvez inverser la sortie grep et la sortie conditionnelle, les mêmes résultats:

for list in `ls` ; do ls -ld $list | grep ^d > /dev/null || echo $list ; done ;
Don R
la source
\dev\null?!?!
Manatwork
0

C'est un fil un peu ancien, mais le moyen le plus propre de ne lister que les fichiers.

ls -al | grep '^-' | awk '{print $9}'
RJ
la source
1
touch "some file name"pour voir un contre
Jeff Schaller
@JeffSchaller Vous avez un point valide. Pour cela quelque chose comme ça. ls -al | grep '^-' | awk '{ for(i=9; i<=NF; ++i) printf $i""FS; print "" }', devrait gérer les fichiers avec des espaces.
RJ