Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Catalog · How the catalog works

Random project

fstats-cli

fstats – Fast Text, Log & Corpus Statistics Profiler.

View on GitHub

Anyone may press Interesting, signed in or not. It helps others find this project.

Member rating

No ratings yet.

Sign in to rate this project.

README

fstats — statistiques de fichiers texte en ligne de commande

Version 2.7.0 · Free Pascal (mode objfpc) · MIT

fstats est un petit outil, rapide et sans dépendances, qui analyse des fichiers texte UTF-8 et affiche des statistiques : caractères, mots, lignes, phrases, mots les plus fréquents, n-grammes, histogrammes… Il peut aussi servir de garde-fou en CI : checks sur des seuils (--fail-if), comparaison à une baseline (--compare) et exit codes dédiés (0/1/2/3).

Il tourne sur Windows et Linux, seul, sans environnement lourd : il suffit du compilateur Free Pascal pour le construire.

👋 Nouveau ici ? Commence par le guide pédagogique : il explique pas à pas, sans jargon, ce que fait l'outil et comment l'utiliser.

Démarrage rapide

Compilation depuis la racine du dépôt :

pascal
fpc -O2 -Mobjfpc -FE. src\fstats.pas

L'exécutable fstats.exe est créé à la racine (wbld.bat fait pareil sous Windows ; wclr.bat nettoie les artefacts de compilation).

Premières analyses :

pascal
fstats mon-fichier.txt          # statistiques compl??tes ?? l'écran
fstats "**/*.md"                # tous les .md du dossier (glob interne)
echo "un deux trois." | fstats - --summary-json   # depuis l'entr??e standard
fstats --json mon-fichier.txt   # export JSON

Ce que fstats sait faire

Domaine Fonctionnalités
Comptage caractères, mots, lignes, phrases, longueur des lignes (min/max/moyenne)
Diagnostic UTF-8 invalide, BOM, fins de ligne CRLF, tabulations, caractères de contrôle
Quality Gate checks sur seuils (--fail-if/--warn-if), baseline (--compare/--fail-on-delta), exit codes 0/1/2/3 pour la CI
Vocabulaire mots uniques, hapax, type-token ratio, longueur moyenne des mots, entropie
Répétitions n-grammes (1 à 5 mots), avec filtrage des mots vides (français/anglais)
Distribution histogrammes (longueur de ligne, de mot, mots par phrase), classes de caractères
Lisibilité mots par phrase, longueur moyenne des mots, % de mots longs (≥ 7), score 0-100 (sans syllabes)
Export console alignée ASCII pur, JSON (objet / NDJSON / tableau / agrégat), CSV

Utilisation

pascal
fstats [options] <fichier|glob|-> [fichier2 ...]

Entrées

Option Effet
-, --stdin Analyse l'entrée standard en UTF-8 (non mélangeable avec des fichiers)
*.txt, **/*.md Patterns glob résolus en interne (CMD/PowerShell n'expandent pas les globs)
--recursive=DIR Parcourt l'arbre de DIR (répétable)
--include=GLOB, --exclude=GLOB Filtres pour --recursive (répétables)
--max-depth=N Profondeur maximale du parcours (0 = racine seule)

Analyse du texte

Option Effet
--word-mode=raw|ascii|unicode Définition des mots (ponctuation incluse ou non)
--casefold=ascii|unicode|none Normalisation des majuscules et des accents
--sentence-mode=basic|smart Fin de phrase : basic (défaut) = . ! ? … + décimales ; smart = + abréviations (M., etc.…) et URLs (https://…)
--lexical-stats Mots uniques, hapax, TTR, longueur moyenne, entropie
--readability Mots par phrase, longueur moyenne des mots, % de mots longs (≥ 7 caractères), score 0-100 — approximation sans syllabes, pas de Flesch-Kincaid exact
--max-unique=N Borne mémoire des mots uniques (défaut 100 000)
--ngrams=N N-grammes sur les mots du mode courant (N = 1..5, fenêtres par ligne)
--top-ngrams=K Limite du top-K des n-grammes (défaut 10 ; 0 = tous)
--stopwords=fr|en|none Retire les mots vides du flux n-gramme uniquement
--histogram=M line_length | word_length | words_per_sentence (barres ASCII)
--char-classes Classe chaque caractère : lettres, chiffres, blancs, ponctuation, contrôle, autre

Checks et comparaison (CI)

Option Effet
--check Mode check : gate CI avec exit codes 2/3 (implicite avec les options ci-dessous)
--fail-if=METRIQUE OPERATEUR SEUIL Check bloquant, répétable (ex. --fail-if max_line_length>120)
--warn-if=METRIQUE OPERATEUR SEUIL Check non bloquant (exit 3 si seulement des warnings)
--compare=BASELINE Compare aux valeurs d'une baseline NDJSON (sortie --summary-json)
--fail-on-delta=METRIQUE>X Check de dérive : échoue si la métrique varie de plus de X % vs baseline

Métriques du gate : lines, words, sentences, max_line_length, avg_words_per_sentence (alias avg_sentence_words), non_utf8 (alias invalid_utf8), bom, crlf, tabs, nonprintable. Opérateurs : >, >=, <, <=, =, !=. (Sous CMD, échapper > : --fail-if lines^>5 ou --fail-if "lines>5".)

Affichage et export

Option Effet
--top-words=N, --top-chars=N Limites des sections Top (défaut 10 ; 0 = tous)
--char, --word, --line, --all Sections « Top » ciblées / toutes les données
--json JSON : 1 fichier = objet ; plusieurs = NDJSON (1 objet par ligne)
--json-mode=ndjson|array|aggregate Forme du JSON multi-fichiers (implique --json)
--summary-json Objet JSON plat par fichier (idéal pour jq et les scripts)
--csv[=summary|words|chars] Export CSV v2 (--csv seul = summary)
--out=FICHIER Écrit la sortie dans un fichier (jamais d'ANSI, jamais de message console)
--quiet Pas de confirmation console avec --out
--color, --no-color Coloriage minimal des titres (console uniquement)
--version, --help, -h Version / aide

Exemples

pascal
fstats examples\demo.obm
fstats --json --out=stats.json examples\demo.obm
fstats --csv=words --all rapport.txt
fstats --recursive=docs --include='**/*.md' --summary-json
echo "un deux trois." | fstats - --json
fstats 'tests/**/*.md' --json-mode=aggregate
fstats --word-mode=ascii --top-words=20 --lexical-stats corpus.txt
fstats --sentence-mode=smart rapport.txt
fstats --sentence-mode=smart --check --fail-if avg_words_per_sentence>25 docs/*.md
fstats --casefold=unicode --lexical-stats --json corpus_fr.txt
fstats --ngrams=3 --top-ngrams=20 --word-mode=ascii corpus.txt
fstats --ngrams=2 --stopwords=fr corpus_fr.txt
fstats --histogram=line_length --histogram=word_length rapport.txt
fstats --char-classes --json corpus.txt
fstats --readability rapport.txt
fstats --readability --word-mode=ascii --summary-json corpus.txt
fstats docs/**/*.md --check --fail-if max_line_length>120 --fail-if non_utf8>0
fstats app.log - --check --fail-if max_line_length>500       # via stdin
fstats --summary-json docs/*.md > baseline.ndjson            # capture
fstats docs/*.md --compare baseline.ndjson --fail-on-delta lines>10
fstats --help

Formats de sortie

  • Console : sections alignées en ASCII pur (Summary, Checks, Quality, Lexical, Readability, Top Characters/Words, Longest Lines, N-grams, Histogram, Character Classes), sans séquence ANSI — sûre pour les scripts et pipes.
  • JSON : champs de traçabilité (tool, version, schema_version, generated) + statistics, quality, et blocs additifs (checks, lexical, readability, ngrams, histogram, char_classes) selon les options.
  • CSV v2 : en-tête fixe file,type,rank,value,code_point,count,length, trois sous-formats (summary, words, chars).

Les détails précis (exemples complets, schémas JSON, ruptures documentées) sont dans la spécification technique.

Codes de retour

Code Signification
0 Succès — analyse OK, ou tous les checks passent
1 Erreur fatale : fichier introuvable, glob sans correspondance, option invalide, sortie inécrivable, stdin mélangé avec des fichiers…
2 Mode check : au moins un check --fail-if/--fail-on-delta échoué
3 Mode check : aucun échec mais au moins un --warn-if déclenché

Les données vont sur stdout ; les erreurs, avertissements et confirmations --out vont sur stderr.

Documentation

Fichier Contenu
doc/GUIDE-PEDAGOGIQUE.md Guide simple : comprendre et utiliser fstats sans jargon
doc/SEMANTIQUE.md Spécification technique : sémantique figée des compteurs, formats JSON/CSV détaillés
doc/VERIFICATION.md Journal de validation (sorties réelles, historique)
doc/ROADMAP-CIBLE1.md Cible 1 « CI / Text Quality Gate » (validée : A v2.2.0, B+C v2.6.0)
doc/ROADMAP-CIBLE2.md Cible 2 « Corpus Profiler » (C2-A v2.3.0, C2-B v2.4.0, C2-C v2.5.0)
doc/ROADMAP-CIBLE3.md Cible 3 « Log Sentinel »
doc/ROADMAPFULL.md Vision d'ensemble et roadmaps complètes
doc/README.md Index de la documentation

Tests automatisés

  • tests\run.bat (Windows / CMD) et tests\run.sh (Linux / Git Bash) : compilation + 59 cas d'acceptation (Cible 1 A/B/C, Cible 2 A/B/C) avec validation JSON via node et vérification des codes de retour.
  • Prérequis : fpc et node sur le PATH.
  • La CI GitHub Actions exécute les deux suites sur windows-latest et ubuntu-latest à chaque push sur main et chaque pull_request.

Structure du projet

pascal
fstats/
????????? .github/workflows/ci.yml  # CI GitHub Actions (Windows + Linux)
????????? doc/                      # Documentation (guide, spec, roadmaps, validation)
????????? examples/demo.obm         # Fichier de d??monstration
????????? src/fstats.pas            # Code source unique (Free Pascal)
????????? tests/                    # Suites de tests + fixtures
????????? LICENSE                   # Licence MIT
????????? README.md

Limites connues (en bref)

  • Fichiers texte UTF-8 uniquement : une séquence invalide est remplacée par U+FFFD et comptée (invalid_utf8).
  • Le BOM est détecté mais conservé (choix assumé).
  • La définition par défaut d'un mot inclut la ponctuation attachée (mode raw) ; --word-mode=ascii|unicode retire la ponctuation.
  • Le case folding unicode est une table basique limitée (accents français/allemand), pas un folding Unicode complet.
  • N-grammes : top-K approximatif sur très gros corpus (sketch mémoire borné) ; non agrégés en --json-mode=aggregate.
  • Un point entre deux chiffres (3.14) ne clôture pas une phrase (v2.6.1) ; un point après un chiffre suivi d'un espace (Version 3.) reste une fin de phrase.
  • Le score de lisibilité (--readability) est une approximation sans syllabes : ce n'est pas un Flesch-Kincaid exact (la formule est figée dans la spécification technique).

Toutes les sémantiques sont détaillées et figées dans la spécification technique.