web-dev-qa-db-fra.com

Comment lister le nombre de lignes de chaque fichier dans un répertoire au format lisible par l'homme.

J'ai une liste de répertoires et sous-répertoires qui contiennent de gros fichiers csv. Il y a environ 500 millions de lignes dans ces fichiers, chacune est un record. J'aimerais savoir

  1. Le nombre de lignes dans chaque fichier.
  2. Combien de lignes sont dans le répertoire.
  3. Combien de lignes au total

Plus important encore, j'ai besoin de cela dans un "format lisible par l'homme", par exemple. 12.345.678 plutôt que 12345678

Ce serait bien d'apprendre à le faire de 3 manières. Outils bash simples de vanille, awk etc., et Perl (ou python).

46
Hexatonic

Le nombre de lignes dans chaque fichier.

Utilisez wc, à l'origine pour le nombre de mots, je crois, mais il peut faire des lignes, des mots, des caractères, des octets et la plus longue longueur de ligne. L'option -l Lui indique de compter les lignes.

wc -l <filename>

Cela produira le nombre de lignes dans:

$ wc -l /dir/file.txt
32724 /dir/file.txt

Vous pouvez également diriger des données vers wc:

$ cat /dir/file.txt | wc -l
32724
$ curl google.com --silent | wc -l
63

Combien de lignes sont dans le répertoire.

Essayer:

find . -name '*.pl' | xargs wc -l

un autre doublure:

( find ./ -name '*.pl' -print0 | xargs -0 cat ) | wc -l

BTW, la commande wc compte les nouveaux codes de lignes, pas les lignes. Lorsque la dernière ligne du fichier ne se termine pas avec le nouveau code de ligne, cela ne sera pas compté.

Vous pouvez utiliser grep -c ^, exemple complet:

#this example prints line count for all found files
total=0
find /path -type f -name "*.php" | while read FILE; do
     #you see use grep instead wc ! for properly counting
     count=$(grep -c ^ < "$FILE")
     echo "$FILE has $count lines"
     let total=total+count #in bash, you can convert this for another Shell
done
echo TOTAL LINES COUNTED:  $total

Combien de lignes au total

Je ne suis pas sûr d'avoir bien compris votre demande. par exemple. cela produira des résultats dans le format suivant, montrant le nombre de lignes pour chaque fichier:

# wc -l `find /path/to/directory/ -type f`
 103 /dir/a.php
 378 /dir/b/c.xml
 132 /dir/d/e.xml
 613 total

Alternativement, pour sortir uniquement le nombre total de nouveaux caractères de ligne sans le nombre de fichiers par fichier pour la commande suivante peut s'avérer utile:

# find /path/to/directory/ -type f -exec wc -l {} \; | awk '{total += $1} END{print total}'
 613

Plus important encore, j'ai besoin de cela dans un "format lisible par l'homme", par exemple. 12.345.678 plutôt que 12345678

Bash a une fonction printf intégrée:

printf "%0.2f\n" $T

Comme toujours, il existe de nombreuses méthodes différentes qui pourraient être utilisées pour obtenir les mêmes résultats mentionnés ici.

66
malyy

Dans de nombreux cas, la combinaison de la commande wc et du caractère générique * peut suffire.
Si tous vos fichiers se trouvent dans un seul répertoire, vous pouvez appeler:

wc -l src/*

Vous pouvez également répertorier plusieurs fichiers et répertoires:

wc -l file.txt readme src/* include/*

Cette commande affichera une liste des fichiers et leur nombre de lignes.
La dernière ligne sera la somme des lignes de tous les fichiers.


Pour compter récursivement tous les fichiers d'un répertoire:

Tout d'abord, activez globstar en ajoutant shopt -s globstar à votre .bash_profile. La prise en charge de globstar nécessite Bash ≥ 4.x qui peut être installé avec brew install bash si besoin. Vous pouvez vérifier votre version avec bash --version.

Exécutez ensuite:

wc -l **/*

Notez que cette sortie sera incorrecte si globstar n'est pas activé.

14
Thomio

Cette commande donnera la liste du code des lignes dans chaque répertoire:

find . -name '*.*' -type f | xargs wc -l
3
Suresh.A

un peu tard pour le jeu, mais j'ai eu un tas d'erreurs d'argument avec ce qui précède en raison de la taille du dir. Cela a fonctionné pour moi:

for i in $(find . -type f); do wc -l $i; done >> /home/counts.txt

2
Ron Paulfan

cat combinerait les fichiers en un seul et afficherait tout sur stdout, vous pouvez faire un wc -l là-dessus pour un nombre total de lignes de fichiers dans un répertoire:

cat /path/to/directory/* | wc -l
1
picmate 涅

Je vais juste augmenter la réponse @malyy pour les éléments suivants (trop gros pour un commentaire):

Combien de lignes au total

De nombreuses réponses utilisent l'option de fichier de ligne de commande wc avec xargs. Le problème avec ceci est que xargs est limité à une taille plutôt petite dépendante de la plateforme.

De plus, il y a une différence entre BSD (macOS) et GNU (linux/homebrew) wc.

Le GNU celui est idéal car il peut lire la liste des fichiers à partir d'un fichier au lieu des arguments (--files0).

Si vous êtes sur Mac et que vous avez un homebrew, vous devez procéder comme suit:

find . -name "*.pl" -print0 | gwc -l --files0=-

Remarquez le gwc au lieu de wc.

1
Adam Gent