Catalog · How the catalog works
fstats-cli
fstats – Fast Text, Log & Corpus Statistics Profiler.
- ★ 1 on GitHub
Anyone may press Interesting, signed in or not. It helps others find 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 :
fpc -O2 -Mobjfpc -FE. src\fstats.pasL'exécutable fstats.exe est créé à la racine (wbld.bat fait pareil sous
Windows ; wclr.bat nettoie les artefacts de compilation).
Premières analyses :
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 JSONCe 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
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
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 --helpFormats 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) ettests\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 :
fpcetnodesur le PATH. - La CI GitHub Actions exécute les deux suites sur
windows-latestetubuntu-latestà chaque push surmainet chaquepull_request.
Structure du projet
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.mdLimites 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|unicoderetire la ponctuation. - Le case folding
unicodeest 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.

