Как извлечь определенный шаблон из файла в HP-UX

Есть несколько способов сделать это с помощью sed. Один из способов - отложенное чтение, как рекомендуется в принятом ответе. Это также можно записать как:

sed -e '$!N;P;/\nPointer/r file1' -e D file2

... с небольшим явным просмотром вперед вместо просмотра назад, реализованного в другом месте с буфером удержания. Однако в этом случае неизбежно возникнет та же проблема с последней строкой, которую отмечает @don_crissti, поскольку N does инкрементирует цикл строки, а команда read применяется по номеру строки.

Это можно обойти:

echo | sed -e '$d;N;P;/\nPointer/r file1' -e D file2 -

Не все sedы будут интерпретировать - как стандартный ввод, но многие это делают. (POSIX говорит sed должен поддерживать - как стандартный ввод, если исполнитель хочет, чтобы - означали стандартный ввод???)

Другой способ - обрабатывать добавляемое содержимое по порядку. Есть еще одна команда, которая schedules выводит так же, как read, а sed применит ее и read в том порядке, в котором они прописаны в сценарии. Однако это немного сложнее - это подразумевает использование одного sed для append Pointer совпадения с выводом другого sed в своем сценарии.

sed '   /Pointer/!d                  #only operate on first match
        s/[]^$&\./*[]/\\&/g;H        #escape all metachars, Hold
        s|.*|/&/!p;//!d|p;g          #print commands, exchange
        s|.|r file1&a\\&|;q' file2|  #more commands, quit
        sed -nf - file2              #same input file

То есть, по сути, первый sed пишет второму sed скрипт, который второй sed читает на стандартном входе (возможно...) и применяет по очереди. Первый sed работает только при первом найденном совпадении для Pointer, после чего quits input. Его задача состоит в том, чтобы...

  1. s/[]^$&\./*[]/\\\&/g;H
    • Убедитесь, что все символы шаблона надежно зашифрованы обратным слешем, потому что второй sed должен будет интерпретировать каждый прочитанный бит буквально, чтобы все было правильно. Как только это будет сделано, поместите копию в Hold space.
  2. s|.*|/&/!p;//!d|p; x
    • Скажите второму sed, чтобы print каждую строку ввода ! кроме той /&/, которую мы только что проверили по шаблону; а затем delete all of the same. print команды на втором sed, затем exchange hold и pattern buffers для работы с нашей сохраненной копией.
  3. s|.|r file1&a\\\\&|p;q
    • Единственный символ, с которым мы здесь работаем, это \newline, потому что sed добавит его, когда мы Held строку до этого. Поэтому мы вставляем команду r file1, за ней следует \newline, затем команда a\\\ для append, за которой также следует \newline. Вся остальная часть нашей строки Held следует за этой последней \newline.

Скрипт, который пишет первый, выглядит примерно так:

/Pointer-file2   "23"/!p;//!d
r file1
a\
Pointer-file2   "23"

В основном второй sed будет печатать все строки, кроме той, которую первый sed установил на append. Для этой конкретной строки две отложенные записи в standard-out будут запланированы - первая будет rначалом file1, а вторая - копией строки, которую мы хотим получить после неё. Первый sed в данном случае даже не нужен (видите? без обратных слешей), но важно безопасно экранировать так, как я это делаю здесь, всякий раз, когда совпадение шаблонов используется в качестве входных данных.

В любом случае... есть несколько способов.

1
07.12.2017, 10:45
0 ответов

Теги

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