Как я могу соответствовать этому тексту в awk, печатая номера строки для соответствий?

Короткий ответ: просто выберите 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.

1
12.12.2011, 00:36
2 ответа

Вот 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

1
27.01.2020, 23:40
  • 1
    . вместо того, чтобы использовать его с Python-c, я просто назвал его чем-то незабываемым (и тематический, начиная с моих различных типов сценариев у всех есть тематические имена), и шлепнулся он в мой $PATH и chmod+x'ed он, вставив #!/usr/bin/env Python наверху. это работает красиво! awk будет чрезвычайно удобен также. –  ixtmixilix 12.12.2011, 17:11

Я записал бы это как это:

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}
'
1
27.01.2020, 23:40

Теги

Похожие вопросы