Обратные ссылки в шаблоне диапазона awk - PullRequest
1 голос
/ 21 октября 2019

У меня есть сценарий, в который я помещаю полезные советы, которые позволяют мне напоминать себе о различных вещах, которые я часто забываю. В настоящее время это выглядит так (но с более полезными советами):

#!/bin/bash
awk 'BEGIN{IGNORECASE = 1}/^.*'$1'.*:$/,/^$/' <<'_EOF'

tip_header:
  tip1:
    actual tip
  <-- white space to here
  tip2:
    another tip
  <-- white space to here
  something:
    else with \weird $characters^~

another_header:
  tip1:
    tip1 for another_header

_EOF

Затем я вызываю tips tip_header, чтобы распечатать все между tip_header: и пустой строкой до another_header: (строкой до tip2: имеет пробел, поэтому не является пустым) или tips tip1 для печати из каждой строки tip1: до следующей пустой строки.

Я хотел бы изменить выражение awk, чтобы endpatсоответствует первой пустой строке с тем же отступом, что и в begpat, поэтому при вызове tips tip1 также не выводится tip2. Что-то вроде:

awk 'BEGIN{IGNORECASE = 1}/^([[:blank:]]*).*'$1'.*:$/,/^\1$/' <<'_EOF'

, но это не работает (я не уверен, как / если можно использовать обратные ссылки в awk или их вариантах). Я не против переключения awk с чем-то еще, что может выполнять многострочное сопоставление с шаблоном.

Редактировать: текущий результат работы tips tip1 равен

brett@brett:~/tmp$ ./tips tip1
  tip1:
    actual tip

  tip2:
    another tip

  something:
    else with \weird $characters^~

  tip1:
    tip1 for another_header

Желаемый результат равен

brett@brett:~/tmp$ ./tips tip1
  tip1:
    actual tip

  tip1:
    tip1 for another_header

при сохранении

brett@brett:~/tmp$ ./tips tip_header
tip_header:
  tip1:
    actual tip

  tip2:
    another tip

  something:
    else with \weird $characters^~

1 Ответ

1 голос
/ 21 октября 2019

Во-первых, позвольте мне настаивать на том, что @tripleee является правильным imo, и вы должны использовать надлежащие инструменты для разбора yaml-файлов.

Если вы действительно хотите использовать awk, я бы сделал что-то безобразное, подобное этому (я пыталсясоздайте код, который будет работать с любой версией awk):

#!/bin/bash
awk -v search="$1" -F '' '
    BEGIN{IGNORECASE = 1}
    (!pos_char)&&($0 ~ (search ".*:")){
    pos_char=1;
        while($pos_char==" "){
            pos_char+=1
        }
        print; next
    } 
    prev_line == "" && NF && pos_char{
        if(NF<pos_char){
            pos_char = 0; next
        }
        for(i=1; i<=pos_char; i++){
            if($i != " "){
                pos_char = 0; next
            }
        }
    }
    pos_char{prev_line=$0;print}
' << '_EOF'

tip_header:
  tip1:
    actual tip

  tip2:
    another tip
with carriage return

  something:
    else with \weird $characters^~

another_header:
  tip1:
    tip1 for another_header

_EOF

Работает, только если вы используете пробелы для отступа. По крайней мере, вы можете удалить уродливые пробельные символы в пустых строках этим методом.

Вывод:

$ ./tips tip
tip_header:
  tip1:
    actual tip

  tip2:
    another tip
with carriage return

  something:
    else with \weird $characters^~

  tip1:
    tip1 for another_header

$ ./tips tip_header
tip_header:
  tip1:
    actual tip

  tip2:
    another tip
with carriage return

  something:
    else with \weird $characters^~

$ ./tips tip1
  tip1:
    actual tip

  tip1:
    tip1 for another_header

$ ./tips tip2
  tip2:
    another tip
with carriage return
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...