Souhaitez-vous que les fichiers soient répertoriés par nombre de lignes, ou que vous en indiquiez le nombre ou les deux? ls -lne donne pas le nombre de lignes. ls -lStrie le fichier par taille avec certaines lsimplémentations (la taille étant le nombre d'octets dans le contenu).
Stéphane Chazelas
Réponses:
34
Vous devriez utiliser une commande comme celle-ci:
find /group/book/four/word/-type f -exec wc -l {}+| sort -rn
find: rechercher des fichiers sur le chemin que vous voulez. Si vous ne le souhaitez pas et que votre findimplémentation le prend en charge, vous devez l'ajouter -maxdepth 1juste avant l' -execoption.
exec: indique à la commande à exécuter wc -lsur chaque fichier.
sort -rn: trier les résultats numériquement dans l’ordre inverse. De plus en plus bas.
(cela suppose que les noms de fichiers ne contiennent pas de caractères de nouvelle ligne).
Notez que lorsqu'il est passé plus d'un fichier (ou avec certaines implémentations, plus d'un fichier qu'il peut lire), wcimprimera également une totalligne, donc ici vous aurez aussi une ou plusieurs lignes "totales" à moins qu'il n'y ait qu'un seul fichier . Vous pouvez diriger pour grep /les supprimer.
Stéphane Chazelas
Vote positif à cause du sortcommandement
Francisco
comment puis-je filtrer pour afficher uniquement les fichiers avec X lignes minimum (exclure X = 0 ligne par exemple)?
Matrix
11
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
wccompte les lignes (option -l) dans tous les *fichiers (mais cachés) ( ) sous /group/book/four/word/, et sorttrie le résultat (par le biais du canal |) numériquement (option -n).
Récursif
Quelqu'un a commenté cette réponse grep -rlcavant de la supprimer. En effet, grepc’est une excellente alternative, surtout si vous avez besoin de récursivité:
comptera (option -c) récursivement (option -r) lignes correspondantes ( grep) '^'(c'est-à-dire, début de lignes) dans le répertoire /group/book/four/word/. Ensuite, vous devez remplacer les deux points par un espace, par exemple en utilisant 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 Stéphane sur les limitations possibles et sur la façon de s'en débarrasser tr.
grep -c .compte les lignes qui contiennent au moins un caractère valide. Utilisez grep -c '^'pour compter toutes les lignes (comptera également les caractères de fin après la dernière nouvelle ligne avec certaines grepimplémentations). Notez que toutes les grepimplémentations ne prennent pas en charge le -rcomportement a et varie selon les utilisateurs. Vous n'avez pas besoin de traduire :s (deux points, pas de point-virgule) en espaces pour sort. Il suffit d'utiliser -t:. Notez que cela suppose que les noms de fichiers ne contiennent pas de caractères :vides ou de nouvelle ligne.
Stéphane Chazelas
1
Merci d’avoir posté votre solution non récursive; Je ne savais pas avoir wcdonné un total aussi pratique si vous passiez par plusieurs chemins. Coupler cette fonctionnalité avec le joker et le tuyau sortest vraiment propre.
Nous définissons une nouvelle fonction de trilines qui répond avec le nombre de lignes du fichier. Et nous utilisons le o+linesqualificatif glob qui, avec n(pour le tri numérique), définit la manière dont les résultats du glob sont ordonnés. ( .également ajouté pour vérifier uniquement les fichiers normaux).
Cela ne fait aucune hypothèse sur le caractère que les noms de fichier peuvent contenir, à part les fichiers cachés (ceux commençant par .) qui sont omis. Ajoutez le Dqualificatif glob si vous le souhaitez également.
@ l0b0 cela ne signifie pas que la prochaine personne qui en aura besoin exécutera également bash.
terdon
4
Vous ne spécifiez pas si vous voulez également les fichiers dans les sous-répertoires de /group/book/four/word. La findsolution dans la réponse de jherran descendra dans les sous-répertoires. Si cela n'est pas souhaité, utilisez plutôt le shell:
for file in ./*; do [ -f "$file" ] && wc -l "$file"; done | sort -n
Si vos noms de fichier peuvent contenir des 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 faites défaut de descendre dans les sous - répertoires, vous pouvez l' utiliser dans bash4 ou au- dessus:
Notez que les versions de bashavant 4.3 suivaient les liens symboliques lors récursive en descendant l'arborescence (comme zsh« s ou tcshd » ***/*).
En outre, toutes les solutions ci-dessus ignoreront les fichiers cachés (ceux dont le nom commence par un ., utilisez-les shopt -s dotglobpour les inclure) et incluront également le nombre de lignes de liens symboliques (ce que l' findapproche ne permettra pas).
Notez que la différence entre la solution de jherran et celle de jherran est que le vôtre considérera également le lien symbolique vers les fichiers normaux ( -xtype fdans GNU find ou *(-.)dans zsh) et omettra les fichiers cachés.
Stéphane Chazelas
@ StéphaneChazelas merci, clarifions. Pourquoi le %ludans printf? Si je me souviens bien, cela signifie une longue décimale non signée, est-ce vraiment nécessaire? Pourquoi ne pas traiter le nombre comme une chaîne? Est-ce que cela fait une différence?
terdon
2
Si la sortie wc est vide (par exemple parce que le fichier n'est pas lisible), 0la chaîne sera étendue à la place de la chaîne vide, ce qui est légèrement meilleur. Certaines implémentations de tri fonctionnent avec des entiers non signés, d'autres avec des signatures. %luCela semble être le pari le plus sûr, mais cela n’a probablement pas d’importance, comme si vous aviez des 2^31lignes, cela prendra de toute façon des siècles.
Stéphane Chazelas
1
Si vous voulez installer fdun outil de recherche de fichiers très rapide écrit en Rust (vous devez l’installer, c’est génial d’avoir de toute façon)
fd --type=file .| xargs wc -l | sort -n
En gros, fdliste les fichiers, xargs passera la liste des fichiers à wc(signifie nombre de mots mais passage -l le fera compter les lignes), puis finalement trié du plus petit nombre de lignes à la plus grande sort -n.
ls -l
ne donne pas le nombre de lignes.ls -lS
trie le fichier par taille avec certainesls
implémentations (la taille étant le nombre d'octets dans le contenu).Réponses:
Vous devriez utiliser une commande comme celle-ci:
find
: rechercher des fichiers sur le chemin que vous voulez. Si vous ne le souhaitez pas et que votrefind
implémentation le prend en charge, vous devez l'ajouter-maxdepth 1
juste avant l'-exec
option.exec
: indique à la commande à exécuterwc -l
sur chaque fichier.sort -rn
: trier les résultats numériquement dans l’ordre inverse. De plus en plus bas.(cela suppose que les noms de fichiers ne contiennent pas de caractères de nouvelle ligne).
la source
wc
imprimera également unetotal
ligne, donc ici vous aurez aussi une ou plusieurs lignes "totales" à moins qu'il n'y ait qu'un seul fichier . Vous pouvez diriger pourgrep /
les supprimer.sort
commandementNon récursif
Probablement la version la plus simple si vous n'avez pas besoin de récursivité:
wc
compte les lignes (option-l
) dans tous les*
fichiers (mais cachés) ( ) sous/group/book/four/word/
, etsort
trie le résultat (par le biais du canal|
) numériquement (option-n
).Récursif
Quelqu'un a commenté cette réponse
grep -rlc
avant de la supprimer. En effet,grep
c’est une excellente alternative, surtout si vous avez besoin de récursivité:comptera (option
-c
) récursivement (option-r
) lignes correspondantes (grep
)'^'
(c'est-à-dire, début de lignes) dans le répertoire/group/book/four/word/
. Ensuite, vous devez remplacer les deux points par un espace, par exemple en utilisanttr
, pour aidersort
, que vous souhaitez trier numériquement (option-n
) sur la deuxième colonne (option-k2
).Mise à jour: Voir le commentaire de Stéphane sur les limitations possibles et sur la façon de s'en débarrasser
tr
.la source
grep -c .
compte les lignes qui contiennent au moins un caractère valide. Utilisezgrep -c '^'
pour compter toutes les lignes (comptera également les caractères de fin après la dernière nouvelle ligne avec certainesgrep
implémentations). Notez que toutes lesgrep
implémentations ne prennent pas en charge le-r
comportement a et varie selon les utilisateurs. Vous n'avez pas besoin de traduire:
s (deux points, pas de point-virgule) en espaces poursort
. Il suffit d'utiliser-t:
. Notez que cela suppose que les noms de fichiers ne contiennent pas de caractères:
vides ou de nouvelle ligne.wc
donné un total aussi pratique si vous passiez par plusieurs chemins. Coupler cette fonctionnalité avec le joker et le tuyausort
est vraiment propre.Avec
zsh
:Nous définissons une nouvelle fonction de tri
lines
qui répond avec le nombre de lignes du fichier. Et nous utilisons leo+lines
qualificatif glob qui, avecn
(pour le tri numérique), définit la manière dont les résultats du glob sont ordonnés. (.
également ajouté pour vérifier uniquement les fichiers normaux).Cela ne fait aucune hypothèse sur le caractère que les noms de fichier peuvent contenir, à part les fichiers cachés (ceux commençant par
.
) qui sont omis. Ajoutez leD
qualificatif glob si vous le souhaitez également.la source
bash
seulement ...Vous ne spécifiez pas si vous voulez également les fichiers dans les sous-répertoires de
/group/book/four/word
. Lafind
solution dans la réponse de jherran descendra dans les sous-répertoires. Si cela n'est pas souhaité, utilisez plutôt le shell:Si vos noms de fichier peuvent contenir des nouvelles lignes, vous pouvez utiliser quelque chose comme:
Enfin, si vous faites défaut de descendre dans les sous - répertoires, vous pouvez l' utiliser dans
bash
4 ou au- dessus:Notez que les versions de
bash
avant 4.3 suivaient les liens symboliques lors récursive en descendant l'arborescence (commezsh
« s outcsh
d »***/*
).En outre, toutes les solutions ci-dessus ignoreront les fichiers cachés (ceux dont le nom commence par un
.
, utilisez-lesshopt -s dotglob
pour les inclure) et incluront également le nombre de lignes de liens symboliques (ce que l'find
approche ne permettra pas).la source
-xtype f
dans GNU find ou*(-.)
dans zsh) et omettra les fichiers cachés.%lu
dansprintf
? Si je me souviens bien, cela signifie une longue décimale non signée, est-ce vraiment nécessaire? Pourquoi ne pas traiter le nombre comme une chaîne? Est-ce que cela fait une différence?0
la chaîne sera étendue à la place de la chaîne vide, ce qui est légèrement meilleur. Certaines implémentations de tri fonctionnent avec des entiers non signés, d'autres avec des signatures.%lu
Cela semble être le pari le plus sûr, mais cela n’a probablement pas d’importance, comme si vous aviez des2^31
lignes, cela prendra de toute façon des siècles.Si vous voulez installer
fd
un outil de recherche de fichiers très rapide écrit en Rust (vous devez l’installer, c’est génial d’avoir de toute façon)En gros,
fd
liste les fichiers, xargs passera la liste des fichiers àwc
(signifie nombre de mots mais passage -l le fera compter les lignes), puis finalement trié du plus petit nombre de lignes à la plus grandesort -n
.la source