Короткий ответ: просто выберите nroff.
Nroff является традиционным текстовым процессором для страниц руководства. Страницы “Catman” являются обычно страницами руководства, которые были отформатированы nroff для использования на текстовом терминале. Страницы Catman имеют мало форматирования, просто полужирный шрифт и подчеркивание, и выравниваются по ширине для особой терминальной ширины (обычно 80 столбцов). В былые времена имело смысл устанавливать предварительно отформатированный (т.е. catman) страницы для предотвращения времени форматирования, но на современном (или даже not-so-modern) машина потраченное форматирование времени незначительно. Некоторые системы имеют кэш так, чтобы каждая исходная страница была отформатирована только однажды, но даже который выходит из употребления. Наличие источника nroff страницы имеет преимущество, что они могут быть отформатированы для другой терминальной ширины, для другой кодировки символов, или для просмотра в нетерминальной установке (веб-браузер, PDF...).
Заглянуть /usr/man
или /usr/share/man
видеть, что уже там. Если Вы видите названные каталоги man
сопровождаемый цифрой, содержащей файлы, которые имеют большое начало строк с точкой, сопровождаемой двумя буквами, Ваша система поддерживает nroff страницы справочника. Если Вы видите названные каталоги cat
сопровождаемый цифрой, содержащей файлы с ^H
символы (число символов 8, который мог бы быть отображен как \010
, \x08
, или обнаружьтесь как подчеркивание или полужирный шрифт), Ваша система поддерживает catman страницы.
На самом деле, даже если один из них отсутствует, большинство систем поддерживает обоих. Например, системы Linux редко имеют любую catman установленную страницу, но действительно поддерживают их. С другой стороны основная установка OpenBSD идет с catman страницами, но поддерживает nroff страницы справочника (которые являются нормой в портах). Несколько систем поддерживают другие форматы также, например, Солярис поставляет некоторые страницы в формате SGML.
Вот awk сценарий, который ищет многострочную строку (соответствия должны состоять из целых строк). Это получает текст для поиска в переменной needle
. Сценарий работает путем создания окна w
строки (где w
количество строк в needle
) и сравнение этого против needle
.
awk -v needle='b 38.\nc 81.\nc 92.\n' '
BEGIN {
if (substr(needle, length(needle)) == "\n")
needle = substr(needle, 1, length(needle)-1);
w = split(needle, needles, "\n");
getline window
for (i = 2; i < w; i++) {getline; window = window "\n" $0}
}
{ window = window "\n" $0 }
window == needle {print NR - w + 1}
{ window = substr(window, index(window, "\n") + 1) }
' <data.txt
Это не самый эффективный способ искать подстроку, потому что каждая строка в файле данных по сравнению с каждой строкой в шаблоне. Существуют более эффективные алгоритмы, которым удается выполнить меньше сравнений путем создания некоторых предварительных вычислений в шаблоне, таких как Knuth-Morris-Pratt.
Для файла, который подходит удобно к памяти, я считал бы все это сразу и выполнил бы поиск в памяти. Если все, что Вы ищете, является соответствием шаблона, это легко сделано в Perl, но Perl испытывает недостаток в примитивах для эффективного отслеживания строки. Вот сценарий Python, который ищет многострочную строку (который должен быть передан как таковой).
import re, sys
needle = sys.argv[1]
haystack = sys.stdin.read()
pos = 0
line = 1
for m in re.finditer(needle, haystack):
line += haystack.count("\n", pos, m.start())
pos = m.start()
print line
Использование: python -c '…' $'b 38.\nc 81.\nc 92.\n' <data.txt
Я записал бы это как это:
awk -v seven_lines="b 34.c 53.b 54.a 45.d 44.d 63.d 64." '
seven_lines == l6 l5 l4 l3 l2 l1 $0 {print "pattern found at line " (NR-6)}
{l6=l5; l5=l4; l4=l3; l3=l2; l2=l1; l1=$0}
'