Не знам как да направя това в grep. Проверих man страницата за egrep(1)
и тя също не може да съвпада с нов ред в средата.
Харесва ми решението, предложено от @Laurence Gonsalves, за използване на tr(1)
за изтриване на новите редове. Но както той отбеляза, ще бъде трудно да отпечатате съвпадащите редове, ако го направите по този начин.
Ако искате да съпоставите въпреки нов ред и след това да отпечатате съвпадащите редове, не мога да измисля начин да го направя с grep, но няма да е твърде трудно в някой от Python, AWK, Perl или Ruby .
Ето скрипт на Python, който решава проблема. Реших, че за редове, които съвпадат само когато са съединени с предишния ред, ще отпечатам стрелка -->
преди втория ред на съвпадението. Редовете, които съвпадат напълно, винаги се отпечатват без стрелката.
Това е написано, като се приема, че /usr/bin/python е Python 2.x. Можете тривиално да промените скрипта, за да работи под Python 3.x, ако желаете.
#!/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])
РЕДАКТИРАНЕ: добавени коментари.
Направих някои проблеми, за да го накарам да отпечата правилния номер на ред на всеки ред, използвайки формат, подобен на този, който бихте получили с grep -Hn
.
Може да е много по-кратко и по-просто, ако нямате нужда от номера на редове и нямате нищо против да прочетете целия файл наведнъж в паметта:
#!/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])
person
steveha
schedule
07.12.2009