Копирование текста с помощью Ctrl + C при активном редакторе строк Zsh

awk 'BEGIN { i=0; }
/^reference:/ { ref[i++] = $0; }
/^sid:/ { for(j=0; j<i; j++) { print ref[j]; print; } i=0; }' inputfile > outputfile

Пояснение:

  • BEGIN { i=0; }Инициализируйте переменную, чтобы убедиться, что она интерпретируется как числовое значение 0, а не как пустая строка "".
  • /^reference:/ { ref[i++] = $0; }Для каждой строки, начинающейся с reference:(^, есть привязка к началу строки ), скопируйте всю строку $0в элемент массива ref[i]и увеличьте индексi++
  • /^sid:/ {... }для каждой строки, начинающейся с sid:...
  • for(j=0; j<i; j++) {... }Поскольку iуказывает на элемент массива после последнего использованного, циклически перебрать все элементы массива, которые были записаны, используя индекс j,
  • print ref[j];вывести содержимое элемента массива, т.е. сохраненную reference:строку
  • print;напечатать текущую строку, то есть строку sid:
  • i=0;сбросить индекс массива на начало следующей группы из reference:строк

Сценарий основан на следующих предположениях:

  • Вход состоит из серии блоков, где каждый блок содержит
    • последовательность из одной или нескольких reference:строк, за которыми следует
    • одна sid:строка
  • Последняя строка должна быть строкой sid:.
  • Строки, не соответствующие -, будут игнорироваться.

В исходном вопросе я предположил неправильное направление преобразования. Второй скрипт конвертирует в обратном направлении:

awk 'BEGIN { oldsid=""; ref=""; }
/^reference:/ { ref=$0; }
/^sid:/ { if(oldsid != $0) { if(oldsid != "") print oldsid; } if(ref!="")print ref; oldsid=$0; }
END { if (oldsid != "") print oldsid; }' inputfile > outputfile

Пояснение:

  • BEGIN { oldsid=""; ref=""; }Инициализируйте переменные для ясности, на самом деле это не обязательно.
  • /^reference:/ { ref=$0; }Для каждой строки, начинающейся с reference:, сохраните строку $0в переменной ref, пока не печатайте ее.
  • /^sid:/ {... }Для каждой строки, начинающейся с sid:...
  • if(oldsid != $0) { if(oldsid != "") print oldsid; }Если строка sid:изменилась сейчас, последняя строка reference:, сохраненная в ref, принадлежит новой строке sid:, поэтому мы ее пока не печатаем. Если oldsidне пусто, мы можем напечатать его сейчас, так как предыдущий блок из reference:строк с таким же sid:закончен. oldsidбудет пустым, когда мы найдем первый sid:.
  • if(ref!="")print ref;Если у нас есть сохраненный reference:, распечатайте его сейчас. (Либо мы только что закрыли предыдущий блок соответствующей строкой sid:, либо теперь мы знаем, что текущий reference:имеет тот же sid:, что и предыдущий. )Проверка на пустую строку на самом деле не нужна, так как я предполагаю, что каждой строке sid:предшествует строка reference:.
  • oldsid=$0;сохранить текущую строку sid:для сравнения, когда мы получим следующую. Текущая строка еще не напечатана.
  • END { if (oldsid != "") print oldsid; }В конце выведите последнюю сохраненную строку sid:, если она есть. (Если входной файл пуст, здесь не будет напечатана пустая строка.)

Этот сценарий основан на этих предположениях:

  • за каждым reference:следуетsid:
  • все пары reference:и sid:с одной и той же строкой sid:следуют друг за другом
1
16.02.2021, 13:55
0 ответов

Теги

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