Question Comment trier les premiers répertoires puis les fichiers, etc ... en utilisant "ls" dans Unix


Je voudrais utiliser le ls commande pour d'abord afficher les répertoires, puis les fichiers. J'ai essayé:

ls -la | sort -k 1

Mais j'ai eu une mauvaise commande.


76
2018-02-16 13:13


origine


c'est parce que - vient avant d en utilisant sort - Nifle
Les anciennes têtes Unix (celles de l'ère pré-GUI) utilisaient les noms de dossiers pour capitaliser et rendre les noms de fichiers non capitalisés pour obtenir ce résultat automatiquement. - JRobert
Question utile! Peut-être est-il temps de changer la réponse acceptée en une réponse plus simple et ne rompant pas les couleurs des terminaux? - ippi


Réponses:


La commande suivante répertorie les répertoires en premier, les fichiers ordinaires en deuxième et les liens tiers.

ls -la | grep "^d" && ls -la | grep "^-" && ls -la | grep "^l"

En outre, il serait très logique de créer un alias pour cette commande pour enregistrer des séquences de touches.

Modifier:

Si vous voulez d'abord les répertoires, puis tout ce qui n'est pas un répertoire, utilisez ceci:

ls -la | grep "^d" && ls -la | grep -v "^d"


25
2018-02-16 13:36



Cette commande ne répertorie pas tout s'il y a, par exemple, des sockets ou des FIFO dans le dossier - Studer
Cette version éditée devrait toujours fonctionner avec d'autres types. Le premier grep dit tout ce qui commence par un "d", et le second dit tout ce qui ne commence pas par un "d". Sûrement, tout commence par un d ou pas, non? - Ry4an Brase
@ Mark - Pourquoi ne pas simplement faire: ls -la | grep "^d" && ls -la | grep "^-" && ls -la | grep -v -E "^d|^-|^total"? - FCTW
Pour que la commande @ FCTW commande un alias OSX, ajoutez-le à votre fichier ~ / .profile: alias la="ls -la | grep \"^d\" && ls -la | grep \"^-\" && ls -la | grep -E \"^d|^-\" -v | grep -v \"^total\"" - aliteralmind
J'ai trouvé une notation plus courte: ls -la|grep ^d;ls -la|grep -v ^d (les devis ne sont pas obligatoires et remplacés && avec ;). Une autre option consiste à introduire une variable et à l'évaluer ensuite: a="ls -la|grep ^d";eval $a;eval $a -v. Cela pourrait être utile pour éviter les répétitions lorsque beaucoup plus d'options sont spécifiées pour ls/grep. Il y a aussi que ls -la --group-directories-first option, cependant la plus courte imo est ls -la|sort - Steven Pribilinskiy


Je l'aime tellement * nix et aime voir l'inventivité qui entre dans certaines de ces réponses ...

Le mien n'est pas aussi sophistiqué sur GNU Linux:

alias ls='ls --color -h --group-directories-first'

Étant donné que je suis plus à l’aise avec mes applications linux CLI, j’ai aussi tendance à mettre à jour coreutils sur OSX:

brew install coreutils
alias ls='/usr/local/bin/gls --color -h --group-directories-first'

176
2018-02-16 13:47



Malheureusement, cela ne fonctionne pas sur le terminal osx car l'option - n'est pas disponible. - MEM
re love: Est-ce le sarcasme? Si oui, je suis d'accord. - allyourcode
Re: Ne fonctionne pas sur mac ... Vraiment, personnellement, je fais généralement une installation de brassage coreutils pour remplacer les macs intégrées pour mon utilisateur local. - jonathanserafini
Le but des alias ls est de définir les éléments de configuration que je veux utiliser 90% du temps. Moins de frappes pour atteindre le résultat souhaité. Si vous voulez avoir une sortie native, vous pouvez toujours / bin / ls. - jonathanserafini
@MEM Si vous utilisez OS X et que vous aimez utiliser Terminal, vous devriez brew install bash  Ensuite, ça va marcher! :) - Andrew Ashbacher


Pour les utilisateurs de Mac coreutils:

brew install coreutils

alias ls='ls --color -h --group-directories-first'

En supposant que votre système est prêt à homebrew:


15
2018-06-13 17:01



gls plutôt. Droite? - Paul Irish
Oui, par défaut Vous pouvez également utiliser coreutils par défaut avec PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH". - benesch


Vous avez plusieurs choix, selon que vous souhaitez conserver l'ordre alphabétique.

Vous pourriez simplement essayer:

ls -al | trier -k1 -r

ou ceci, pour conserver l'ordre alphabétique des fichiers avec les mêmes autorisations:

ls -al | sort -k1,1 -k9,9 -r

ou, comme on l’a dit onze81 (mais cette version liste tout):

ls -la | grep "^ d" && ls -la | grep "^ -" && ls -al | grep -v "^ [d | -]"


6
2018-02-16 14:28



Ceci est une meilleure solution IMO. L'utilisation de plusieurs processus et tuyaux pour effectuer le tri au lieu de la mise en forme par tri semble un peu en arrière. Spécialement depuis ls- al|sort -k1 -r travaux. Ce qui manquait c'est juste le -r drapeau. - brice
@brice La chose qui me dérange à propos de «tri» est que ./ et ../ ne seront pas les deux premières lignes, dans cet ordre. À part cela, je suis d’accord que c’est la solution la plus efficace. - thdoan


À délire010 réponds, j'ajouterais que si vous voulez une commande à l'ancienne:

LANG=C ls -la --group-directories-first

(ou utilisez LC_ALL ou LANGUAGE ou LC_COLLATE défini sur "C").

Cela donnera quelque chose de similaire à:

.
..
DIR
Dir
dir
.hidden
123
UC_FILE
Uc_file
lc_file

Bien que, si je me souviens bien, les fichiers de points cachés sont apparus à l'origine avant les répertoires.


5
2018-02-16 14:56





Il y a certaines choses que je veux voir dans une liste de répertoires, et jusqu'à présent, aucune des réponses ne répond à toutes les exigences ci-dessous. Mes exigences pour une liste de répertoire:

  1. Les répertoires et les fichiers sont triés par ordre alphabétique
  2. Les répertoires sont listés en premier
  3. Les liens symboliques (liens symboliques) sont triés comme des fichiers
  4. Le tri est sensible à la casse
  5. Le tri ignore tous les caractères non alpha principaux dans un nom de fichier
  6. La liste inclut le nombre total d’annuaires ./ et ../), des fichiers et des liens
  7. La liste inclut la taille totale (utilisation du disque) des répertoires et des fichiers
  8. La liste doit être la même sur Linux et Windows (shell Git Bash) - ce fut le plus difficile à obtenir puisque des options pratiques comme --group-directories-first ne fonctionne pas dans Git Bash pour Windows

Après beaucoup de piratage, j'ai finalement trouvé un one-liner (quoique très long ;-)) avec lequel je suis satisfait. Je l'ai assigné à un alias nommé 'dir':

ls -dlF --color * .* | head -n2 && ls -AlF | LC_ALL=C grep "^d" | 
LC_ALL=C sort -k 9df && ls -AlF | LC_ALL=C grep "^[l-]" | 
LC_ALL=C sort -k 9df && echo -e `find -maxdepth 1 -type d ! -name . | 
wc -l` Dir\(s\) `du -hs | cut -f 1`\\t\\t`find -maxdepth 1 -type f | 
wc -l` File\(s\) `find -maxdepth 1 -type f -print0 | du -ch --files0-from=- | 
tail -n 1 | cut -f 1`\\t\\t`find -maxdepth 1 -type l | wc -l` Link\(s\)

Pour rendre les choses plus faciles à gérer, je suis arrivé avec des commandes séparées pour sortir chaque segment de la liste des répertoires à mon goût, puis les ai assemblés en utilisant le && opérateur.

  • ls -dlF --color * .* | head -n2 -- Extrait ./ et ../. Nous ne voulons pas passer ces travers sort parce qu'ils sont déjà dans le bon ordre, et leur tri peut entraîner ../ étant répertorié en premier. le -dl'option est de se débarrasser de la ligne "total"; J'aime ajouter -F pour afficher la barre oblique des répertoires (il marquera également les liens symboliques avec "@" lorsque vous faites une plaine) ls -F).

  • ls -AlF | LC_ALL=C grep "^d" | LC_ALL=C sort -k 9df - Extraire les répertoires et les trier par nom de fichier (9ème colonne), en ignorant les caractères non-alpha / espace (d option) et la casse des caractères (f option). le ls -A option exclut ./ et ../ de la liste puisque nous les avons déjà extraits à l'étape précédente. J'ai tendance à préfixer tout grep et sort commandes avec le LC_ALL=C réinitialisation des paramètres régionaux de sorte que (1) la sortie soit cohérente entre les shells Unix, et (2) vous pouvez parfois voir des performances plus rapides, car le jeu de caractères lourd UTF-8 n'est plus surchargé.

  • ls -AlF | LC_ALL=C grep "^[l-]" | LC_ALL=C sort -k 9df - Ceci est similaire à l'étape ci-dessus, mais cette fois, nous trions les fichiers et les liens symboliques.

  • find -maxdepth 1 -type d ! -name . | wc -l - Récupère le nombre de répertoires, à l'exclusion de ./ et ../.

  • find -maxdepth 1 -type f | wc -l - Obtenez le nombre de fichiers.

  • find -maxdepth 1 -type l | wc -l - Récupère le nombre de liens symboliques.

  • du -hs | cut -f 1 - Extraire la taille totale de tous les sous-répertoires dans un format lisible par l'homme.

  • find -maxdepth 1 -type f -print0 | du -ch --files0-from=- | tail -n 1 | cut -f 1 - Extraire la taille totale de tous les fichiers dans un format lisible par l'homme.

Voyons notre nouveau dir alias en action!

AVANT:

$ ls -alF
total 22
drwxr-xr-x   13 Tom      Administ     4096 Oct 25 02:38 ./
drwxr-xr-x    3 Tom      Administ        0 Dec 24  2014 ../
drwxr-xr-x   15 Tom      Administ     4096 Sep 17 01:23 .VirtualBox/
-rw-r--r--    1 Tom      Administ      615 Oct 25 02:38 .aliases
-rw-r--r--    1 Tom      Administ    12742 Oct 24 11:47 .bash_history
-rw-r--r--    1 Tom      Administ     3234 Oct 24 15:06 .bash_profile
drwxr-xr-x    1 Tom      Administ        0 Jan 24  2015 .gem/
-rw-r--r--    1 Tom      Administ      586 Oct 24 03:53 .gitconfig
drwxr-xr-x    1 Tom      Administ     4096 Dec 28  2014 .ssh/
drwxr-xr-x    4 Tom      Administ        0 Jan 24  2015 .travis/
-rw-r--r--    1 Tom      Administ     6645 Oct 25 02:38 _viminfo
-rw-r--r--    1 Tom      Administ     4907 Oct 24 15:16 profile
drwxr-xr-x    1 Tom      Administ        0 Oct 24 22:20 tmp/

APRÈS:

$ dir
drwxr-xr-x   13 Tom      Administ     4096 Oct 25 02:38 ./
drwxr-xr-x    3 Tom      Administ        0 Dec 24  2014 ../
drwxr-xr-x    1 Tom      Administ        0 Jan 24  2015 .gem/
drwxr-xr-x    1 Tom      Administ     4096 Dec 28  2014 .ssh/
drwxr-xr-x    1 Tom      Administ        0 Oct 24 22:20 tmp/
drwxr-xr-x    4 Tom      Administ        0 Jan 24  2015 .travis/
drwxr-xr-x   15 Tom      Administ     4096 Sep 17 01:23 .VirtualBox/
-rw-r--r--    1 Tom      Administ      615 Oct 25 02:38 .aliases
-rw-r--r--    1 Tom      Administ    12742 Oct 24 11:47 .bash_history
-rw-r--r--    1 Tom      Administ     3234 Oct 24 15:06 .bash_profile
-rw-r--r--    1 Tom      Administ      586 Oct 24 03:53 .gitconfig
-rw-r--r--    1 Tom      Administ     4907 Oct 24 15:16 profile
-rw-r--r--    1 Tom      Administ     6645 Oct 25 02:38 _viminfo
      5 Dir(s) 2.8M           6 File(s) 31K           0 Link(s)

Un inconvénient mineur est que vous ne pouvez pas avoir de listes colorées, car les caractères de contrôle de couleur entourant les noms de fichiers rendent le tri peu fiable.


METTRE À JOUR

L'alias ci-dessus était terriblement lent lorsqu'il était exécuté à partir du répertoire racine d'un système de fichiers profond, j'ai donc mis à jour cette commande plus simple mais beaucoup plus performante:

ls -AFoqv --color --group-directories-first | tail -n +2 && find -maxdepth 1 -type f -printf '%s\n' | awk '{total+=$1} END {print total" bytes"}'

Sortie de l'échantillon:

$ dir
drwxr-xr-x 1 Tom     0 Mar 29 13:49 .aws/
drwxr-xr-x 1 Tom     0 Mar 29 13:49 .gem/
drwxr-xr-x 1 Tom     0 Mar 29 19:32 .ssh/
drwxr-xr-x 1 Tom     0 Mar 29 13:49 .zbstudio/
drwxr-xr-x 1 Tom     0 Jun 16  2016 temp/
drwxr-xr-x 1 Tom     0 Jul 13  2016 vimfiles/
-rw-r--r-- 2 Tom   365 Mar 30 10:37 .aliases
-rw-r--r-- 1 Tom 16028 Mar 30 12:12 .bash_history
-rw-r--r-- 2 Tom  2807 Mar 30 12:12 .bash_profile
-rw-r--r-- 2 Tom  2177 Mar 29 23:24 .functions
-rw-r--r-- 1 Tom  1091 Mar 30 10:34 .gitconfig
-rw-r--r-- 1 Tom  8907 Mar 29 14:45 _viminfo
-rw-r--r-- 1 Tom  2444 Jul 13  2016 _vimrc
33819 bytes

Depuis la nouvelle version de Git Bash pour Windows prend en charge --group-directories-first, on ne doit plus se rabattre sur sort. Même si le nouvel alias n’affiche pas autant d’informations que l’alias précédent, les gains de performances en valent largement la peine. En tant qu'avantage, vous obtenez également des couleurs!


4
2017-10-24 20:07



Très bonne réponse! Mais quand tu dis, "Après beaucoup de piratage, j'ai finalement trouvé un one-liner ..." Oui, en effet ce n'est pas vraiment un "one liner" au sens classique du terme. Il peut être judicieux de prendre cette logique et d'en faire un script shell autonome et de l'exécuter ou de l'appeler comme un alias. - JakeGould
@JakeGould Vous êtes rapide! Je n'ai même pas encore fini de relire ma réponse et vous avez déjà fini de la lire et de tirer un commentaire :). Oui, c'est un candidat de choix pour une fonction, mais j'étais trop paresseux à ce moment-là, donc je l'ai jeté dans mon fichier .bash_aliases. Par contre, je n'écris généralement qu'une fonction lorsque je ne peux pas faire quelque chose sans passer de paramètres. - thdoan
@ 10basetom: Question rapide: Comment obtenez-vous les différentes couleurs pour les colonnes dans ls? Je peux colorier noms de fichiers par type de fichier en utilisant ls --color, mais je ne vois pas comment obtenir ces couleurs utiles pour les colonnes. Quel est le secret? - Pirx
@Pirx Je crois que les colonnes sont colorées par la mise en évidence de la syntaxe Stack Exchange par défaut :-). - thdoan
Ouais, cela semble être le cas, mais c'est une excellente idée, et les solutions sont dans :-) - Pirx


Voici une fonction pour faire ceci (bash ou zsh): Et ... je ne suggère pas que ce soit la meilleure façon, mais c'est celle que j'ai proposée et que j'utilise maintenant:

fonction lss
{
    # Affiche la liste de répertoires avec les répertoires en haut.

    commande ls --color = toujours $ @ | egrep '^ d | total'
    commande ls --color = toujours $ @ | egrep -v '^ d | total';
}

2
2018-02-16 13:37



Juste un fyi cela ne semble pas fonctionner. Vous devez utiliser le format long listing (ls -l) afin de filtrer par type de fichier comme ça. En outre, cette commande va casser sur les espaces (en bash). Vous devez citer comme suit: "$@" Si vous souhaitez utiliser cette approche, vous pouvez faire quelque chose comme ça: function lss {local temp="$(command ls -l --color=always "$@")"; egrep --color=never '^d|total' <<<"$temp"; egrep --color=never -v '^d|total' <<<"$temp"} - Six


Autrement ...

find . -d 1 -type d | ls -la | sort -r 

OU

ls -la | sort -r

OU

d=`find . -type d -d 1`;f=`find . -type f -d 1`; echo -e -DIRS- "\n$d\n" -FILES- "\n$f"

1
2018-06-08 09:57



Que font-ils? Où avez-vous appris à les taper? - Tom Wijsman
Eh bien, mon système d'exploitation préféré est Debian Linux. La version du paquet gnu core utils de Debian de ls supporte l'option --show-Directories-first ... quand j'ai commencé à utiliser OSX, j'ai simplement récupéré tous mes fichiers de point bash depuis ma boîte Debian et les ai déposés dans mon répertoire personnel ... Il y avait beaucoup de bash_aliases qui ont cassé alors ... C'est à ce moment-là que j'ai dû trouver des solutions pour mes alias ... - Eddie B
Le premier est un peu redondant ... Il n'y a vraiment aucune raison de trier les répertoires car c'est l'ordre de modifier non les répertoires ... le 'ls -la | sort -r 'est ce qui fonctionne vraiment. Fondamentalement, il dit ... 1) A) Find. -d 1 -type d (Démarrer à partir de ce répertoire, rechercher une profondeur de répertoire et rechercher uniquement les répertoires) B) ls -la (lister les fichiers tous les attributs) C) les classer en sens inverse 2) Faire comme 1) .. ce n'est pas nécessaire ... j'aime mieux la solution de Studers ... :-) - Eddie B


ls -laX affichera d'abord les répertoires par ordre alphabétique, mais videra la liste des fichiers.

Options longues:

ls
    -l    # List
    --all
    -X    # Sort alphabetically by entry extension

1
2018-02-16 13:31



Cela ne fonctionnerait que si vous pouviez être absolument certain que chaque répertoire ne comportait aucun point. - eleven81