No sé cómo hacer esto en grep. Revisé la página del manual para egrep(1)
y tampoco puede coincidir con una línea nueva en el medio.
Me gusta la solución @Laurence Gonsalves sugirió, de usar tr(1)
para eliminar las nuevas líneas. Pero como señaló, será doloroso imprimir las líneas correspondientes si lo haces de esa manera.
Si desea hacer coincidir a pesar de una nueva línea y luego imprimir la (s) línea (s) correspondiente (s), no puedo pensar en una forma de hacerlo con grep, pero no sería demasiado difícil en Python, AWK, Perl, o Ruby.
Aquí hay una secuencia de comandos de Python que resuelve el problema. Decidí que, para las líneas que solo coinciden cuando se unen a la línea anterior, imprimiría una flecha -->
antes de la segunda línea del partido. Las líneas que coinciden directamente se imprimen siempre sin la flecha.
Esto se escribe suponiendo que/usr/bin/python es Python 2.x.Puede cambiar trivialmente la secuencia de comandos para trabajar en Python 3.x si así lo desea.
#!/usr/bin/python
import re
import sys
s_pat = "export\s+to\s+excel"
pat = re.compile(s_pat)
def print_ete(fname):
try:
f = open(fname, "rt")
except IOError:
sys.stderr.write('print_ete: unable to open file "%s"\n' % fname)
sys.exit(2)
prev_line = ""
i_last = -10
for i, line in enumerate(f):
# is ete within current line?
if pat.search(line):
print "%s:%d: %s" % (fname, i+1, line.strip())
i_last = i
else:
# construct extended line that included previous
# note newline is stripped
s = prev_line.strip("\n") + " " + line
# is ete within extended line?
if pat.search(s):
# matched ete in extended so want both lines printed
# did we print prev line?
if not i_last == (i - 1):
# no so print it now
print "%s:%d: %s" % (fname, i, prev_line.strip())
# print cur line with special marker
print "--> %s:%d: %s" % (fname, i+1, line.strip())
i_last = i
# make sure we don't match ete twice
prev_line = re.sub(pat, "", line)
try:
if sys.argv[1] in ("-h", "--help"):
raise IndexError # print help
except IndexError:
sys.stderr.write("print_ete <filename>\n")
sys.stderr.write('grep-like tool to print lines matching "%s"\n' %
"export to excel")
sys.exit(1)
print_ete(sys.argv[1])
EDITAR: agregó comentarios.
Me tomé la molestia de imprimir el número de línea correcto en cada línea, usando un formato similar al que obtendría con grep -Hn
.
Podría ser mucho más corto y más simple si usted no necesita los números de línea, y no te importa la lectura en todo el archivo a la vez en la memoria:
#!/usr/bin/python
import re
import sys
# This pattern not compiled with re.MULTILINE on purpose.
# We *want* the \s pattern to match a newline here so it can
# match across multiple lines.
# Note the match group that gathers text around ete pattern uses a character
# class that matches anything but "\n", to grab text around ete.
s_pat = "([^\n]*export\s+to\s+excel[^\n]*)"
pat = re.compile(s_pat)
def print_ete(fname):
try:
text = open(fname, "rt").read()
except IOError:
sys.stderr.write('print_ete: unable to open file "%s"\n' % fname)
sys.exit(2)
for s_match in re.findall(pat, text):
print s_match
try:
if sys.argv[1] in ("-h", "--help"):
raise IndexError # print help
except IndexError:
sys.stderr.write("print_ete <filename>\n")
sys.stderr.write('grep-like tool to print lines matching "%s"\n' %
"export to excel")
sys.exit(1)
print_ete(sys.argv[1])
Según tengo entendido (referencia: Unix Power Tools), la familia de programas grep está orientada a la línea, lee una línea a la vez y, por lo tanto, no puede encontrar patrones en la línea. Así que puedes pensar en un script en Perl o usar sed aquí. HTH. – sateesh
cómo usar sed en este contexto? –
@Vijay: echo -e "foo \ nbar" | sed -n 'N;/foo \ nbar/p' – SiegeX