$ cat phrase #! /bin/sh # phrase -- search for words across two lines. # Prints the line number # $1 = search string; remaining args = filenames search=$1 shift for file do sed -n ' /'"$search"'/b final N h s/.*\n// /'"$search"'/b final g s/ *\n// /'"$search"'/{ g b final } g D :final = p ' $file doneAsí, con el ejemplo ``multiline.test'' usado anteriormente obtenemos la siguiente salida:
$ phrase "Owner and Operator Guide" multiline.test 3 Section 3.1 in the Owner and Operator Guide for a description of the tape drives available for the Owner 7 Consult Section 3.1 in the Owner and Operator Guide for a description of the tape drives 10 Look in the Owner and Operator Guide, we mean the Owner 14 Two manuals are provided including the Owner and Operator Guide and the User Guide. 16 The Owner and Operator Guide is shipped with your system. 19 Look in the Owner and Operator Guide shipped with your system.Primero se busca el patrón
/'"$search"'/
en la línea actual.
Observe el habilidoso uso de las comillas simples y dobles para permitir
la sustitución de la variable. La primera comilla simple cierra
la comilla simple al final de la línea 10. Las comillas dobles
hacen que la shell sustituya permite continuar el texto sin sustituciones.
Si se encuentra el patrón de búsqueda, imprimimos el número de línea (comando =) y la línea.
Si no, leemos la siguiente línea, formando un patrón multilínea.
Salvamos las dos líneas en el hold space.
Entonces intentamos buscar el patrón /'"$search"'/
en
la línea que acaba de incorporarse. Es por eso que eliminamos
del espacio de patrones la primera línea con la orden
s/ *\n//
. Si se encuentra, imprimimos y se repite el ciclo.
Si no, recuperamos las dos líneas del hold space
sustituimos el retorno de carro por un blanco y realizamos
una nueva busqueda.
Si tiene éxito, se obtienen las dos líneas y se imprimen.
En caso contrario, esto es, si el patrón no se ha encontrado en ninguna
de las dos líneas, es necesario preservar la última para el siguiente
ciclo. Por eso, se obtienen una vez mas las líneas del hold space
y se suprime con D la primera de ellas. Dado que D
devuelve el control al comienzo del script, la segunda línea no es eliminada.
De todos modos, el script no es capaz de captar cuando un prefijo del patrón
aparece al final de esta segunda línea, como muestra el
ejemplo de prueba. En el primer párrafo el patrón se encuentra
dos veces y sólo es encontrado una.
Casiano Rodríguez León