Я не знаю, как это сделать в grep. Я проверил справочную страницу для 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