Come cercare il testo in un file ignorando le nuove righe?


11

Vorrei cercare un testo che può essere suddiviso su più righe in un file. Un grep che ignorerebbe le interruzioni di riga e restituirebbe l'intervallo di righe corrispondente.

ad esempio, sarei alla ricerca is an example filee mi aspetto che si trovi nel seguente file:

Questo è
un
file di esempio.

Non dipendere da spazi iniziali o finali, ignorare completamente tutte le forme di spazio bianco potrebbe essere la cosa migliore (idealmente, trattando qualsiasi sequenza di spazio bianco come un singolo spazio).


Una soluzione non ideale è tr '\n' ' ' | grep, che discrimina tra partite e non partite, ma non mostra la partita, né si occupa bene di file di grandi dimensioni.


su SO (nessuna risposta definitiva): stackoverflow.com/q/1858312/1449460
Nikana Reklawyks

Come nota a margine, la ricerca di emacs sembra fare il lavoro ( isearch-forward)
Nikana Reklawyks,

Così fa Vim di: /This\_sis. Per maggiori informazioni: :help \_s.
lcd047,

Aggiungi questa riga alla fine della riga di ricerca: tr -n "\ n" Questo rimuoverà tutte le nuove righe. Spero che questo aiuto!
Dan Howel,

Risposte:


12

La GNU greppuò farlo

grep -z 'is\san\sexample\sfile.' file

Per soddisfare alcuni punti che sorgono nei commenti ci sono alcune modifiche allo script:

 grep -oz '^[^\n]*\bis\s*an\s*example\s*file\.[^\n]*' file

Per quanto riguarda i file di grandi dimensioni, non ho immaginazione di limitare la memoria, ma in caso di problemi sei libero di usare sed

sed '/\bis\b/{
          :1
          N
          /file\.\|\(\n.*\)\{3\}/!b1
         }
     /\<is\s*an\s*example\s*file\./p
     D' file

che mantengono non più di 4 righe (perché 4 parole nel modello) in memoria ( \(\n.*\)\{3\}).


5
Come sono sicuro che sai, l' -zopzione dice grepdi trattare le nuove righe come normali caratteri di testo e cercare null byte per separare i record. In un file di testo senza byte nulli (ovvero il caso tipico), grep -zl'intero file verrà trattato come una riga. Quindi (1) questo solleva la questione di quanto sia in grado di gestire file di grandi dimensioni e (2) se trova una corrispondenza, scriverà l'intero file, senza fornire indicazioni sulla posizione della corrispondenza. Inoltre (3) l'OP ha detto, "idealmente, trattando qualsiasi sequenza di spazi bianchi come un unico spazio", quindi è necessario utilizzare \s+e aggiungere -E.
G-Man dice "Reinstate Monica"

1
@ G-Man Grazie per il commento. Si prega di vedere la risposta modificata.
Costas,

1
(0) Ah -o,; Continuo a dimenticarmene. Modo intelligente per usarlo. (1) La tua nuova greprisposta ha inizio ^[\n]*; questo è un refuso per [^\n]*. (2) Ho detto \s+deliberatamente.  be\s*littlecorrisponderà belittlee care\s*lesscorrisponderà careless. Ma immagino che sia un problema minore. E, se non si desidera utilizzare -E, è possibile utilizzare “la versione del povero” di \s+, vale a dire, \s\s*. (3) Bel sedcomando. Può fallire se ci sono righe vuote (quindi la frase di quattro parole può estendersi su più di quattro righe); Sono stato in grado di risolvere il problema aggiungendo s/\n\s*\n/\n/.
G-Man dice "Reinstate Monica"

@ G-Man Grazie againg. I tuoi commenti sono molto utili. Ho provato a pubblicare codice più o meno portatile perché membri famosi ogni volta mi spingono a farlo. Comunque anche senza di -Ete l'acciaio è in grado di utilizzare +nella \s\+forma. Le linee vuote all'interno del modello sembrano essere inventate.
Costas,

Stavo pensando a documenti di testo impaginati, come gli RFC - ISTR secondo cui le pagine man sembrano simili su alcuni sistemi (o lo hanno fatto ) - ma, a proposito, mi viene in mente che la maggior parte di tali documenti hanno intestazione e / o piè di pagina (s) che dovrebbero essere rimossi prima di poter sperare in greploro per le frasi.
G-Man dice "Reinstate Monica"

7

Prova questo:

pcregrep -M '\bThis\s+is\b' <<EOT
This
is
an example
file.
EOT

Devo digitare \s5 volte se cerco "questo è un modello molto lungo"?
Nikana Reklawyks

1
Sì: il punto \scorrisponde agli spazi e newline è uno "spazio".
lcd047,

Voglio dire, cosa succede se il file è This\nis a very\nlong patterne non so dove potrebbero verificarsi le interruzioni di riga. Dovrei cercare This\sis\sa\svery\slong\spattern, giusto? (che diventa noioso man mano che la lunghezza del motivo aumenta o viene incollato da altrove)
Nikana Reklawyks,

2
Poi lo si fa in questo modo: pcregrep -M "$( echo 'This is a very long pattern' | sed 's/ /\\s+/g' )" file.
lcd047,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.