5 votes

Un moyen simple d'analyser et d'interroger des contenus semi-structurés de plusieurs lignes.

Il m'arrive de travailler avec des fichiers texte dans lesquels certaines sections comportent plusieurs paragraphes ayant la même structure. En voici un exemple :

Some unrelated preface I'm not interested in... Lorem ipsum dolor sit amet, 
consectetur adipiscing elit. Etiam scelerisque. 
Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
Etiam scelerisque. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam scelerisque. 

001 [SomeTitle 1] - Some Subtitle 1
  Name: SomeName
  Area: SomeArea
  Content: Some multi-line comment...Lorem ipsum dolor sit amet, consectetur 
           adipiscing elit. Etiam scelerisque. Lorem ipsum dolor sit amet, 
           consectetur adipiscing elit. Etiam scelerisque. 

002 [SomeTitle 2] - Some Subtitle 2
  Name: SomeOtherName
  Area: SomeOtherArea
  Content: Some other multi-line comment...Lorem ipsum dolor sit amet, consectetur 
           adipiscing elit.

Je cherche un moyen simple d'interroger des fichiers de ce type. Par exemple, si je recherche "Area:SomeOtherArea", le résultat devrait être tous les blocs du fichier contenant cette zone. Je veux dire les quatre paragraphes : En-tête, Nom, Zone, Contenu. Je pourrais utiliser grep avec les options -A et -B, mais le problème est que les paragraphes de contenu peuvent être composés d'un nombre quelconque de lignes. Et ce n'est que cet exemple spécifique ; la structure pourrait être complètement différente.

Je recherche une solution légère et facilement adaptable, peut-être une combinaison d'outils CLI. Je ne veux pas réinventer la roue.

2voto

shellter Points 15304

Désolé de le dire, mais il n'y a qu'une limite à ce que vous pouvez faire avec ce genre de problème, car vous semblez vouloir un couteau suisse avec un ensemble de fonctionnalités infiniment extensibles, mais sans aucune douleur de votre part pour la programmation :-) ! Une telle chose est modérément possible, mais étant donné votre spécification très ouverte, rappelez-vous que les gens passent des années à construire des moteurs de recherche comme Lucene, Google et des milliers d'autres pour résoudre ce genre de problème.

Cela dit, si vous pouvez vous contenter d'un outil de recherche qui a une règle très simple à respecter, ET si vous utilisez ou avez accès à un système Unix/Linux/Cygwin, ce qui suit peut fonctionner.

Règle de base : les blocs de données seront recherchés sur la base d'un blanc comme séparant chaque bloc (comme dans votre exemple de données ci-dessus).

cat paraSearch.ksh

#!/bin/ksh
#  (or #!/bin/bash or likely others)

case $# in 0 ) echo "usage:paraSearch.ksh SearchTargetPattern file2search [file2 ....]" ; exit 1 ;;esac

# read the first pattern as the search target, 
# use quotes on cmd-line if you want to use
# regexp chars like '*'
mySrchPat="$1" ; shift

#dbg set -vx
awk  -v mySrchPattern="$mySrchPat"   \
  'BEGIN{RS=""; ORS="\n\n"}
  #dbg {print "$0="$0; print "----------------------------------------------" }
  $0 ~ mySrchPattern{ print $0}
' "${@}"

chmod 755 paraSearch.ksh

test en utilisant votre texte d'exemple et searchTarget ET la sortie

$ ./paraSearch.ksh SomeName multiLineTest.txt
001 [SomeTitle 1] - Some Subtitle 1
  Name: SomeName
  Area: SomeArea
  Content: Some multi-line comment...Lorem ipsum dolor sit amet, consectetur
           adipiscing elit. Etiam scelerisque. Lorem ipsum dolor sit amet,
           consectetur adipiscing elit. Etiam scelerisque.

Pour en savoir plus sur awk, lisez (plusieurs fois) cet excellent tutoriel : Le tutoriel Awk de la Grymoire .

IHTH

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X