2009-12-13 20 views
6

Pregunta realmente básica aquí. Entonces me dijeron que un punto. coincide con cualquier carácter, EXCEPTO un salto de línea. Estoy buscando algo que coincida con cualquier personaje, incluidos los saltos de línea.¿Hay un comodín verdaderamente universal en Grep?

Todo lo que quiero hacer es capturar todo el texto en una página web entre dos cadenas específicas, pelando el encabezado y el pie de página. Algo así como HEADER TEXT (. +) FOOTER TEXT y luego extrae lo que está entre paréntesis, pero no puedo encontrar una manera de incluir todos los saltos de texto Y texto entre el encabezado y el pie de página, ¿tiene sentido esto? ¡Gracias por adelantado!

Respuesta

7

Cuando necesito para que coincida con varios personajes, incluyendo los saltos de línea, que hago:

[\s\S]*? 

Nota que estoy usando un patrón no expansivo

+2

¡Gracias chicos! Qué sitio tan amigable y útil. Olvidé mencionar que estaba usando grep search en BBEdit, esto funciona maravillosamente. ¡Todos ustedes rock! –

3

Se podía hacerlo con Perl:

$ perl -ne 'print if /HEADER TEXT/ .. /FOOTER TEXT/' file.html 

Para imprimir sólo el texto entre los delimitadores, utilice

$ perl -000 -lne 'print $1 while /HEADER TEXT(.+?)FOOTER TEXT/sg' file.html 

El interruptor /s hace que el matcher expresión regular el tratamiento de toda la cadena como una s línea ingle, que significa punto coincide con líneas nuevas, y /g significa coincidencias tantas veces como sea posible.

Los ejemplos anteriores asumen que está arrancando archivos HTML en el disco local. Si tiene que buscarlos en primer lugar, utilizar get de LWP::Simple:

$ perl -MLWP::Simple -le '$_ = get "http://stackoverflow.com"; 
          print $1 while m!<head>(.+?)</head>!sg' 

Tenga en cuenta que el análisis de HTML con expresiones regulares que el anterior no funciona en el caso general! Si está trabajando en un escáner rápido y sucio, está bien, pero para una aplicación que necesita ser más robusta, use un analizador real.

1

Como se señaló en otro lugar, grep funcionará para cosas de una sola línea.

fines de múltiples líneas (en rubí con Regexp :: MULTILINE, o en Python, awk, sed, lo que sea), "\ s" debe también captar los saltos de línea, por lo

HEADER TEXT(.*\s*)FOOTER TEXT 

podría funcionar .. .

+0

Tendría que leer el archivo en un modo que escanea varias líneas en la memoria para que funcione. –

+0

Gracias, agregué cómo harías eso en Ruby. IIRC, eso es/g en perlish, ¿no? – phtrivier

2

La página del manual de grep dice:

grep, egrep, fgrep, rgrep - líneas de impresión que coincidan con un patrón

grep no está hecho para coincidir más de una línea. Intente resolver esta tarea con perl o awk.

3

Por definición, grep busca líneas que coincidan; lee una línea, ve si coincide, e imprime la línea.

Una manera posible de hacer lo que quiere decir con sed:

sed -n '/HEADER TEXT/,/FOOTER TEXT/p' "[email protected]" 

Esto imprime desde la primera línea que coincide con 'texto de cabecera' a la primera línea que coincide con 'pie de página', y luego repite; la '-n' detiene la operación predeterminada 'imprimir cada línea'. Esto no funcionará bien si el texto del encabezado y pie de página aparece en la misma línea.

Para hacer lo que quiera, probablemente usaría perl (pero podría usar Python si lo prefiere). Consideraría sorber todo el archivo y luego usar una expresión regular adecuadamente calificada para encontrar las partes coincidentes del archivo. Sin embargo, el delineador de Perl dado por '@gbacon' es una transliteración casi exacta en Perl del script 'sed' anterior y es más nítido que sorber.

0

He aquí una manera de hacerlo con gawk, si lo tienes

awk -vRS="FOOTER" '/HEADER/{gsub(/.*HEADER/,"");print}' file 
2

Como esto está etiquetado con 'BBEdit' y BBedit soporta modificadores del patrón Perl-style que puede permitir que el punto para que coincida con saltos de línea con el interruptor (? s)

(? S).

coincidirá con CUALQUIER carácter. Y sí, (? S). + coincidirá con el texto completo.

Cuestiones relacionadas