web-dev-qa-db-fra.com

Liste des fichiers triés par le nombre de lignes qu'ils contiennent

Comment afficher le nombre de lignes dans les fichiers de /group/book/four/Word, triés par le nombre de lignes qu'ils contiennent?

ls -l la commande les répertorie mais ne les trite pas

33
Ken R

Vous devriez utiliser une commande comme celle-ci:

find /group/book/four/Word/ -type f -exec wc -l {} + | sort -rn
  • find: recherche de fichiers sur le chemin de votre choix. Si vous ne le souhaitez pas, et votre implémentation de votre find l'aide, vous devriez ajouter -maxdepth 1 juste avant le -exec option.
  • exec: indique à la commande d'exécuter wc -l sur chaque fichier.
  • sort -rn: Triez les résultats numériquement dans l'ordre inverse. De plus en plus bas.

(qui suppose que les noms de fichiers ne contiennent pas de caractèresWLINE).

36
jherran

Non récursif

Probablement la version la plus simple si vous n'avez pas besoin de récursivité:

wc -l /group/book/four/Word/*|sort -n

wc comptes lignes (option -l) dans chaque (mais caché) (*) Les fichiers sous /group/book/four/Word/, et sort trie le résultat (à travers le tuyau |) numériquement (option -n).

Récursif

Quelqu'un a fait un commentaire à cette réponse mentionnant grep -rlc, avant de le supprimer. En effet grep est une excellente alternative, surtout si vous avez besoin de récursivité:

grep -rc '^' /group/book/four/Word/|tr ':' ' '|sort -n -k2

comptera (option -c) récursivement (option -r) Les lignes correspondantes (grep) '^' (c'est-à-dire, début des lignes) dans le répertoire /group/book/four/Word/. Ensuite, vous devez remplacer le côlon par un espace, par exemple Utilisation tr, pour aider sort, que vous souhaitez trier numériquement (option -n) sur la deuxième colonne (option -k2).

Mise à jour: Voir le commentaire de Stephane sur les limitations possibles et comment vous pouvez vous débarrasser de tr.

12

Avec zsh:

lines() REPLY=$(wc -l < $REPLY)
print -rC1 /group/book/four/Word/*(.no+lines)

Nous définissons une nouvelle fonction trilines qui répond avec le nombre de lignes dans le fichier. Et nous utilisons le o+lines Qualificatif global qui avec n (pour le tri numérique), définit la manière dont les résultats du GLOB sont commandés. (. a également ajouté pour vérifier uniquement les fichiers réguliers).

Cela ne fait aucune hypothèse sur quel caractère les noms de fichier peuvent contenir autres fichiers cachés (ceux commençant par .) sont omis. Ajouter le qualificatif D Glob si vous le souhaitez aussi.

La définition d'une fonction lines est utile lorsque vous faites souvent quelque chose comme ça, mais pour un seul off, vous pourriez aussi le faire en une fois avec:

print -rC1 /group/book/four/Word/*(.noe['REPLY=$(wc -l < $REPLY)'])

D'une autre coquille, il suffit de courir:

zsh -c '
  print -rC1 /group/book/four/Word/*(.noe['\''REPLY=$(wc -l < $REPLY)'\''])'

Ou pour le stocker dans un ksh93/bash tableau si vous avez vraiment dû utiliser ces coquilles:

typeset -a array
eval "
  array=(
    $(
      zsh -c '
        () {
          print -r -- "${(qq)@}"
        } /group/book/four/Word/*(N.noe['\''REPLY=$(wc -l < $REPLY)'\''])'
    )
  )
"

(ici en utilisant une citation appropriée à une citation unique (avec le drapeau d'expansion de paramètre qq) pour le evaludue pour être sûr).

8
Stéphane Chazelas

Vous ne spécifiez pas si vous souhaitez également les fichiers de tous les sous-répertoires de /group/book/four/Word. La solution find dans la réponse de Jherhan va descendre dans les sous-répertoires. Si cela n'est pas recherché, utilisez la coquille à la place:

for file in ./*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

Si vos noms de fichier peuvent contenir de nouvelles lignes, vous pouvez utiliser quelque chose comme:

for file in ./*; do 
    [ -f "$file" ] && 
        printf "%lu %s\0" "$(wc -l < "$file")" "$file"
done | sort -zn | tr '\0' '\n'

Enfin, si vous DO Voulez-vous descendre dans des sous-répertoires, vous pouvez l'utiliser dans bash 4 ou plus:

shopt -s globstar
for file in ./**/*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

Notez que les versions de bash antérieures à 4.3 suivaient des liens symboliques lorsqu'ils décrivent de manière récursive l'arborescence de répertoire (comme zsh 's ou tcsh' s ***/*).

En outre, toutes les solutions ci-dessus ignoreront les fichiers cachés (ceux dont le nom commence par un ., utilisation shopt -s dotglob Pour les inclure) et inclura également le nombre de lignes de liens symboliques (que l'approche find ne sera pas).

4
terdon

Si vous souhaitez installer fd Un trouveur de fichiers vraiment rapide écrit dans Rust (vous devez l'installer, c'est bon d'avoir de toute façon)

fd --type=file . | xargs wc -l | sort -n

Fondamentalement fd répertorie les fichiers, Xargs transmettra la liste des fichiers à wc (représente le nombre de mots, mais le transparaissant le rendra compte des lignes de comptage), alors elle est finalement triée du moins de lignes à Le plus grand utilisant sort -n.

2
JustGage

Étant donné que la solution fournie par @skippylegrandgourou n'a pas fonctionné pour moi, voici ma solution récursive en utilisant find:

find <folder> -name "<filter>" -exec wc {} \; | sort

Exemple:

find . -name "*.jsp" -exec wc {} \; | sort
0
Cristian Traìna