web-dev-qa-db-fra.com

Comment trier les premiers répertoires puis les fichiers etc… quand on utilise “ls” dans Unix

J'aimerais utiliser la commande ls pour afficher d’abord les répertoires, puis les fichiers. J'ai essayé:

ls -la | sort -k 1

Mais j'ai un mauvais ordre.

86
atricapilla

La commande suivante listera les répertoires en premier, les fichiers ordinaires en second et les liens en troisième.

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

En outre, il serait judicieux de créer un alias pour que cette commande enregistre les 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"

26
eleven81

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

Le mien n’est pas aussi sophistiqué que 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 également tendance à mettre à jour coreutils sur OSX:

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

Pour les utilisateurs de Mac coreutils :

brew install coreutils

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

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

16
Vadym Tyemirov

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

Vous pouvez simplement essayer:

ls -al | trier -k1 -r

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

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

ou, comme le dit onze81 (mais cette version énumère tout):

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

6
Studer

Pour répondre à de delerious010, j'ajouterais que si vous souhaitez une commande à l'ancienne:

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

(ou utilisez LC_ALL ou LANGUAGE ou LC_COLLATE réglé sur "C").

Cela donnera quelque chose de similaire à:

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

Bien que, si je me souvienne bien, les fichiers à points cachés sont apparus avant les répertoires.

5
Dennis Williamson

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

  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 insensible à la casse
  5. Le tri ignore tous les principaux caractères non-alpha d'un nom de fichier
  6. La liste comprend le nombre total de répertoires (à l'exception de ./ et ../), de fichiers et de liens.
  7. La liste comprend la taille totale (utilisation du disque) des répertoires et des fichiers
  8. La liste doit avoir le même aspect sous Linux et Windows (Git Bash Shell) - c’était le plus difficile à comprendre, car les options pratiques comme --group-directories-first ne fonctionnent pas dans Git Bash pour Windows.

Après de longues discussions, j'ai finalement trouvé un one-liner (bien que très long ;-)) dont je suis satisfait. J'ai assigné ceci à 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, j'ai créé des commandes distinctes pour générer chaque segment de la liste de répertoires à mon goût, puis je les ai assemblées à l'aide de l'opérateur &&.

  • ls -dlF --color * .* | head -n2 - Extrait ./ et ../. Nous ne voulons pas les passer par sort car ils sont déjà dans le bon ordre et leur tri peut donner la priorité à ../. L'option -d consiste à supprimer la ligne "total"; J'aime ajouter -F pour afficher la barre oblique de fin des répertoires (cela marquera également les liens symboliques avec "@" lorsque vous ferez un ls -F en clair).

  • ls -AlF | LC_ALL=C grep "^d" | LC_ALL=C sort -k 9df - Extrayez les répertoires et triez-les par nom de fichier (9ème colonne), en ignorant les caractères non-alpha/espace (option d) et la casse des caractères (option f). L'option ls -A exclut ./ et ../ de la liste puisque nous les avons déjà extraites à l'étape précédente. J'ai tendance à préfixer toutes les commandes grep et sort avec la réinitialisation de la locale LC_ALL=C de sorte que (1) la sortie soit cohérente sur les shells Unix et (2) vous pouvez parfois voir des performances plus rapides car elle ne supporte plus le lourd fardeau du lourd UTF-8. jeu de caractères à traiter.

  • 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 des fichiers et des liens symboliques.

  • find -maxdepth 1 -type d ! -name . | wc -l - Obtenir le nombre de répertoires, à l'exception de ./ et ../.

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

  • find -maxdepth 1 -type l | wc -l - Obtenir le nombre de liens symboliques.

  • du -hs | cut -f 1 - Extrait 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 - Extrait la taille totale de tous les fichiers dans un format lisible par l'homme.

Voyons notre nouvel alias dir 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 la couleur entourant les noms de fichiers rendent le tri trop peu fiable.


UPDATE

L'alias ci-dessus était douloureusement 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"}'

Exemple de sortie:

$ 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

Puisque la nouvelle version de Git Bash pour Windows prend en charge --group-directories-first, nous n’avons plus besoin de nous replier sur sort. Même si le nouvel alias n'affiche pas autant d'informations que l'ancien, les gains de performances en valent la peine. En tant qu'avantage, vous obtenez également des couleurs!

5
thdoan

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

Longues options:

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

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 créée et que j'utilise en ce moment:

 function lss 
 {
 # Affiche la liste des répertoires avec les répertoires en haut. 
 
 commande ls --color = always $ @ | egrep '^ d | total' 
 commande ls --color = always $ @ | egrep -v '^ d | total'; 
} 
2
SuperMagic

TL; DR

alias ls='ls -lhF --color'

list_sorted() {
    ls $* | grep "^d";
    ls $* | grep "^-";
    ls $* | grep -v -E "^d|^-|^total"
}

alias ll=list_sorted

Explication

J'utilise une combinaison des solutions fournies dans les réponses et les commentaires ici.

lspar défaut

Tout d’abord, j’écrase le comportement par défaut de lsname__:

  • -l: Toujours afficher la liste sous forme de liste verticale unidimensionnelle
  • -h: Affiche la taille des fichiers selon un mode lisible par l'homme (p. ex. 4,0 Ko au lieu de 4096)
  • -F: Afficher les indicateurs comme une barre oblique de fin pour les répertoires
alias ls='ls -lhF --color'

ll__ étendu

Ensuite, j'écris une fonction contenant la logique de tri. Pour chaque lsname__, je lui transmets tous les arguments initialement transmis. Cela me permet d’utiliser l’alias à partir d’un répertoire de travail différent de celui que je veux lister (c.-à-d. ls -a ~).

En outre, chaque appel à lsest dirigé vers une commande grepname__. Ici, le tri se passe. ls -l | grep "^d" par exemple ne répertorie que les répertoires. Si les répertoires doivent être répertoriés en premier, cela doit également figurer en premier dans la fonction. La prochaine chose est les fichiers.

Enfin, je montre tout ce qui n'est ni un répertoire ni un fichier (ni la ligne indiquant la taille totale du contenu du répertoire). Ceci est fait en grepping directoy, les entrées de fichier normales et l'entrée totale, puis en inversant le résultat via l'argument -v.

list_sorted() {
    # List directories
    ls $* | grep "^d";
    # List regular files
    ls $* | grep "^-";
    # List everything else (e.g. symbolic links)
    ls $* | grep -v -E "^d|^-|^total"
}

Enfin, j'appelle la fonction à une nouvelle commande. En particulier, je ne souhaite pas écraser lsau cas où ma fonction serait interrompue dans certains scénarios. Ensuite, je veux pouvoir utiliser lsname__. Vous pouvez également toujours invoquer la commande lssans alias en appelant \ls.

alias ll=list_sorted

Remarques

  • J'utilise ; au lieu de && en tant que délimiteur pour les commandes. Sinon, il est impossible de répertorier le contenu des répertoires ne contenant pas de répertoires (la première commande ls est évaluée à false, ne permettant donc pas l’exécution de la commande suivante car elle est associée à &&. ; permet d’éviter cela.)
1
kleinfreund

Autrement ...

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

OR

ls -la | sort -r

OR

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

Ceci est une solution de script. Répertorie uniquement les noms, pas de données inode, alphabétiques, non sensibles à la casse, formatés en colonnes. Bien que ce soit ligne-majeur au lieu de colonne majeure comme la sortie par défaut de ls. Les colonnes sont un peu en désordre s'il existe un nom de fichier de> 26 caractères.

rm -f /tmp/lsout
ls -1p | grep / | sort -f >> /tmp/lsout
ls -1p | grep -v / | sort -f >> /tmp/lsout

IFS=$'\n' read -d '' -r -a lines < /tmp/lsout

printf "%-24s  %-24s  %-24s\n" "${lines[@]}"

Et un autre, avec un formatage supplémentaire.

rm -f /tmp/lsout
echo "  ---- Directories ---- " >> /tmp/lsout
ls -1p | grep / | sort -f >> /tmp/lsout
IFS=$'\n' read -d '' -r -a lines < /tmp/lsout
printf "%-24s  %-24s  %-24s\n" "${lines[@]}"

rm -f /tmp/lsout
echo "  ------- Files ------- " >> /tmp/lsout
ls -1p | grep -v / | sort -f >> /tmp/lsout
IFS=$'\n' read -d '' -r -a lines < /tmp/lsout
printf "%-24s  %-24s  %-24s\n" "${lines[@]}"

La sortie pour le dernier ressemble à ceci, moins les couleurs:

  ---- Directories ----   archive/                  bookmarks/              
Desktop/                  Documents/                Downloads/              
fff/                      health/                   Library/                
Movies/                   Music/                    Pictures/               
Public/                   rrf/                      scifi/            
testdir/                  testdir2/                                         
  ------- Files -------   @todo                     comedy            
delme                     lll                       maxims                  
schedule                  vtokens style

Rappelez-vous simplement de ne pas alias ou de changer le comportement par défaut de ls puisque ce script l’appelle.

0
Igorio