Я не знаю, как это сделать в grep. Я проверил справочную страницу на egrep(1)
, и она не может совпадать с новой строкой в середине.
Мне нравится решение, предложенное @Laurence Gonsalves, об использовании tr(1)
для удаления новых строк. Но, как он отметил, печатать совпадающие строки будет сложно, если вы сделаете это таким образом.
Если вы хотите сопоставить, несмотря на новую строку, а затем вывести соответствующие строки, я не могу придумать, как это сделать с помощью grep, но это было бы не слишком сложно в любом из Python, AWK, Perl или Рубин.
Вот скрипт 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])