2012-12-03 11 views
5

Di tanto in tanto lavoro con file di testo in cui alcune sezioni hanno più paragrafi con la stessa struttura. Ecco un esempio:Un modo semplice di analizzare e interrogare il contenuto semistrutturato multi-linea

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. 

Sto cercando un modo semplice per interrogare i file di questo tipo. Ad esempio, se lo interrogassi per "Area: SomeOtherArea", il risultato dovrebbe essere tutti i blocchi del file con quell'area. Intendo tutti e quattro i paragrafi: Intestazione, Nome, Area, Contenuto. Potrei usare grep con le opzioni -A e -B, ma il problema è che i paragrafi di contenuto possono essere costituiti da un numero qualsiasi di righe. E questo è solo questo esempio specifico; la struttura potrebbe essere completamente diversa.

Sto cercando una soluzione leggera e facilmente adattabile, forse una combinazione di strumenti CLI. Non voglio reinventare la ruota.

+0

scorrere il mouse su ciascuno dei tag assegnati alla domanda. Alcuni hanno zero seguaci. Meglio cambiare i tuoi tag per includere almeno il SO di destinazione (Unix/vs/Linux/vs/Windows/vs/Cygwin/...?) E gli strumenti che ti piacciono, una shell? bash/ksh e aggiungi i tuoi strumenti di ricerca grep, ?? altri. In bocca al lupo. – shellter

risposta

2

Mi spiace dirlo, ma è solo così lontano che puoi andare con questo tipo di problema, visto che sembri voler un coltellino svizzero con un insieme infinitamente espandibile di funzioni, ma senza alcun dolore da parte tua per la programmazione: -)! Una cosa del genere è moderatamente possibile, ma data la tua specifica ampia aperta, ricorda che le persone trascorrono anni costruendo motori di ricerca come Lucene, Google e migliaia di altri per risolvere questo tipo di problema.

Detto questo, se si può essere felici con uno strumento di ricerca che ha una regola molto semplice che deve essere rispettata, E si sta utilizzando o si ha accesso a un sistema Unix/Linux/Cygwin, quanto segue può funzionare.

Regola base: i blocchi di dati verranno cercati in base a uno spazio vuoto come separare ciascun blocco (come nei dati campione sopra indicati).

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 con il testo di esempio e searchTarget e l'uscita

$ ./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. 

Per saperne di più su awk, leggere (più volte) questo ottimo tutorial: The Grymoire's Awk Tutorial.

IHTH