Extraire les citations d’un article source avec un gabarit à quatre champs

Une citation qui chevauche deux lignes ne sort pas de grep -oE : le motif s’arrête au retour à la ligne et la phrase reste invisible. Le manuel GNU grep donne la raison, « fundamentally line-based », et conseille de transformer l’entrée. Deux étapes préparent les citations : pdftotext (poppler-utils 22.12.0-2+deb12u1 sur Debian 12) écrit une page par fichier, puis tr replie chaque page sur une ligne. grep -oE en tire les passages entre guillemets. Extraire les citations d’un article source fait partie de la rédaction assistée par IA.
Sommaire
- 1. pdftotext écrit une page à la fois, tr la replie sur une seule ligne
- 2. grep -oE sort chaque citation sur sa propre ligne, avec sa page
- 3. Le gabarit tient en quatre champs : page, citation, auteur, contexte
- 4. Binary file page-13 matches : grep cache la ligne au lieu de l’afficher
- 5. pandoc coupe la sortie texte à 72 colonnes, –wrap=none l’en empêche
- 6. Une police abîmée ou un scan ne rendent aucun texte
- Une citation publiée sans sa page ne se vérifie plus
- Sources
1. pdftotext écrit une page à la fois, tr la replie sur une seule ligne
pdftotext écrit une page à la fois, et le tiret placé à la place du fichier de sortie envoie le texte sur la sortie standard. La page de manuel Debian définit -f comme la première page à convertir et -l comme la dernière ; sans fichier de sortie, pdftotext transforme article.pdf en article.txt. Aucun message ne signale la réussite. Une boucle fabrique ensuite un fichier par page et confie chaque page à tr, qui remplace retours à la ligne et sauts de page par des espaces.
sudo apt install poppler-utils pdfinfo article.pdf for p in $(seq 1 42) do pdftotext -f "$p" -l "$p" article.pdf - | tr -s ' \n\f' ' ' > "page-$p" done ls page-* | wc -l
Ce qu’on doit voir : pdfinfo affiche le nombre de pages, et le 42 de la boucle reprend ce nombre ; la boucle ne dit rien ; ls page-* | wc -l confirme le total ; wc -l sur page-12 renvoie 0, la page tient sur une seule ligne. L’encodage de pdftotext vaut UTF-8 par défaut.
2. grep -oE sort chaque citation sur sa propre ligne, avec sa page
grep -o imprime chaque portion de ligne qui correspond au motif, une portion par ligne. Le motif «[^»]*» prend tout ce qui se trouve entre un guillemet ouvrant et un guillemet fermant, espaces insécables comprises, et ne laisse rien de côté. L’option -E active les expressions régulières étendues ; -H ajoute le nom du fichier, ce que grep fait déjà dès qu’il reçoit plusieurs fichiers. sort -V compare les suites de chiffres comme des nombres, sinon page-10 passerait avant page-2.
grep -HoE '«[^»]*»' page-* | sort -V
Ce qu’on doit voir : une ligne par citation, préfixée par le nom du fichier, du type page-12:« … », dans l’ordre croissant des pages.
Le motif suppose une locale UTF-8. La page de manuel grep(1) de Debian 12 (grep 3.8-5) rappelle qu’en locale C ou POSIX « all characters are encoded as a single byte » : l’espace insécable se lit octet par octet, et la classe s’arrête avant la fin. Le guillemet fermant n’est jamais atteint, la citation disparaît. La commande locale montre le réglage ; LC_ALL sur fr_FR.UTF-8 rétablit la sortie.
3. Le gabarit tient en quatre champs : page, citation, auteur, contexte
Deux champs sortent du terminal, deux se remplissent à la main. Le gabarit garde la page d’origine, la citation recopiée sans retouche, l’auteur nommé dans l’article et le contexte, la question à laquelle la phrase répond. La commande suivante écrit quatre colonnes séparées par des tabulations dans citations.tsv, les deux dernières vides. Le fichier s’ouvre dans un tableur ou un éditeur de texte.
| Champ | Origine de la valeur | Format attendu | Contrôle avant publication |
|---|---|---|---|
| page | préfixe du nom de fichier, page-12 | nombre entier | la citation se relit à cette page dans le lecteur PDF |
| citation | sortie de grep -oE | phrase entre guillemets, recopiée sans retouche | accents et ponctuation identiques au PDF |
| auteur | phrase qui introduit la citation | prénom et nom, ou fonction exacte | un nom, jamais « le rapport » ni « l’étude » |
| contexte | rédaction | une ligne, quinze mots maximum | la citation se comprend hors du paragraphe |
grep -HoE '«[^»]*»' page-* | sort -V | while IFS=: read -r nom citation
do
p="${nom#page-}"
printf '%s\t%s\t\t\n' "$p" "$citation"
done > citations.tsv
Ce qu’on doit voir : head -3 citations.tsv affiche une ligne par citation, quatre colonnes séparées par des tabulations, les deux dernières encore vides. Un deux-points présent dans la citation reste dans la deuxième colonne.
L’auteur se lit dans la phrase qui précède la citation, souvent avec « selon » ou « explique ». La fenêtre suivante montre les 120 caractères d’avant, sur la page concernée. Le contexte vient du brief d’un article source quand il existe : la citation répond à une question déjà posée.
grep -oE '.{0,120}«[^»]*»' page-12
4. Binary file page-13 matches : grep cache la ligne au lieu de l’afficher
grep répond Binary file page-13 matches dès que le fichier contient un octet NUL ou des octets invalides dans la locale courante. La page de manuel Debian définit ces octets comme « output bytes that are improperly encoded for the current locale, or null input bytes when the -z option is not given », et signale que le message part sur la sortie d’erreur. Le fichier extrait n’a pas changé, c’est la lecture de grep qui bascule.
Binary file page-13 matches
Le remède documenté est l’option -a, équivalente à --binary-files=text, qui traite le fichier comme du texte. Un avertissement du manuel accompagne l’option : -a peut recracher des octets de contrôle sur un terminal, et pour un encodage inconnu il conseille -a ou LC_ALL='C'. L’option -I fait l’inverse, elle supprime le message et considère le fichier comme sans correspondance.
5. pandoc coupe la sortie texte à 72 colonnes, –wrap=none l’en empêche
pandoc --wrap=none empêche la découpe des lignes dans la sortie texte ; le réglage par défaut, lui, plie le texte à 72 colonnes. Le manuel de pandoc donne la valeur exacte, « With auto (the default), pandoc will attempt to wrap lines to the column width specified by –columns (default 72) ». Une citation qui dépasse cette largeur se retrouve coupée en deux, et grep -oE ne la voit plus.
sudo apt install pandoc pandoc --wrap=none -t plain article.docx -o article.txt
Ce qu’on doit voir : avec --wrap=none, wc -l compte une ligne par paragraphe, au lieu d’une ligne tous les 72 caractères. Le PDF n’appartient pas aux formats d’entrée de pandoc, mais figure dans sa liste de sortie : un article en PDF passe par pdftotext.
| Format du fichier source | Outil et paquet Debian 12 | Valeur par défaut |
|---|---|---|
| pdftotext, poppler-utils 22.12.0-2+deb12u1 | article.txt créé depuis article.pdf, saut de page entre deux pages | |
| docx | pandoc 2.17.1.1-2~deb12u1 | lignes coupées à 72 colonnes |
| HTML | pandoc 2.17.1.1-2~deb12u1 | texte brut avec -t plain, même pliage à 72 colonnes |
6. Une police abîmée ou un scan ne rendent aucun texte
Certains PDF embarquent des polices dont l’encodage est méconnaissable ; la page de manuel de pdftotext tranche dans sa section BUGS, « There is no way (short of OCR) to extract text from these files ». La chaîne d’extraction ne peut que constater le vide. Un PDF scanné tombe dans la même impasse, la page n’étant qu’une image sans couche de texte. wc -c sur le fichier page-12 donne la taille en octets et signale le problème.
OCRmyPDF, dont la documentation porte la version 17.12.1, « adds an optical character recognition (OCR) text layer to scanned PDF files ». La commande ocrmypdf -l fra article.pdf article-ocr.pdf exige le paquet de langue française, puis pdftotext relit le fichier obtenu. Sur un PDF qui contient déjà du texte, l’outil s’arrête sur le message ERROR – 1: page already has text! ; --skip-text laisse ces pages intactes.
Pour un document de trois pages, cette mécanique est un détour : ouvrir le PDF dans un lecteur, sélectionner la phrase et la coller dans le gabarit va plus vite. La chaîne prend l’avantage dès que la sélection à la souris devient laborieuse, et Stirling-PDF réduit le fichier aux pages utiles avant l’extraction.
Une fois les quatre colonnes remplies, vérifier les affirmations avant publication prend le relais.
Une citation publiée sans sa page ne se vérifie plus
Faut-il pandoc ou pdftotext pour un article en .docx ?
pandoc lit le .docx, pdftotext ne lit que le PDF : un article au format Word passe par pandoc --wrap=none -t plain article.docx -o article.txt. Le réglage --wrap=none évite les lignes coupées à 72 colonnes, qui rendent les citations longues invisibles à grep -oE. pandoc 2.17.1.1-2~deb12u1 s’installe avec apt sur Debian 12.
Comment retrouver la page exacte d’une citation ?
Extrayez le PDF page par page avec pdftotext -f 12 -l 12, un fichier par page, puis grep -H préfixe chaque citation par le nom du fichier, du type page-12:« … ». Le numéro de page est dans ce préfixe, et la boucle reprend le nombre de pages affiché par pdfinfo.
Pourquoi grep répond-il Binary file page-13 matches au lieu des citations ?
Le fichier contient un octet NUL ou des octets mal encodés pour la locale courante : grep le classe binaire et remplace les lignes par ce message, envoyé sur la sortie d’erreur. L’option -a, équivalente à --binary-files=text, force la lecture en texte et rend les citations. -I fait l’inverse et ignore le fichier.
Deux citations identiques apparaissent deux fois, comment dédoublonner ?
Retirez le préfixe du nom de fichier avec grep -hoE, puis triez : grep -hoE '«[^»]*»' page-* | sort -u garde une seule ligne par texte de citation. La page se retrouve ensuite avec grep -F 'début de la citation' page-*, dont chaque ligne de sortie commence par le nom du fichier.
Combien coûte la chaîne d’extraction ?
Rien : poppler-utils s’installe depuis les dépôts Debian avec sudo apt install poppler-utils, pandoc avec sudo apt install pandoc, et la page de manuel grep(1) de Debian décrit grep comme un logiciel libre, « This is free software ». Aucun compte n’est nécessaire, les commandes lisent un fichier local pour écrire un fichier local. Le seul coût réel reste la lecture des citations.
Faut-il la dernière version de poppler pour extraire des citations ?
Non. Debian 12 fournit poppler-utils 22.12.0-2+deb12u1, dont la page de manuel documente toutes les options utilisées ici. La version stable du projet poppler, 26.09.0, date du 3 septembre 2026 ; ses notes signalent l’ajout de l’option -urls à pdftotext, qui affiche les URL des liens à côté du texte. Cette option ne change rien à l’extraction des passages entre guillemets.
Sources
- pdftotext(1) et pdfinfo(1), pages de manuel Debian 12, poppler-utils 22.12.0-2+deb12u1
- GNU grep, manuel officiel, sections Usage, File and Directory Selection et Environment Variables
- Pandoc User’s Guide, options –wrap et –columns
- Poppler, notes de version de la 26.09.0, publiée le 3 septembre 2026
- OCRmyPDF, documentation officielle, version 17.12.1