Соответствует n-му вхождению шаблона и удаляет его, пока не будет найден другой шаблон с несколькими скобками - PullRequest
0 голосов
/ 25 января 2019

Я хочу написать скрипт оболочки, который будет соответствовать символу "%", и удалять все, пока не будет найден конкретный символ. Конкретный символ находится в скобках [A-G], [a-g], [m-n], [p-s]. Например, я хотел бы изменить %0.h2d на %d.

Я рассмотрел множество решений до сих пор и не нашел того, что искал, особенно в отношении нескольких скобок. Мой первоначальный план с кодом ниже состоял в том, чтобы сначала изолировать строку и затем выполнить удаление:

awk '{for(i=1;i<=NF;i++) {if ($i == "%") beginning=i; if($i == [ A-G ] || $i ==    [ a-g ] || $i ==[ m-n ] || $i == [ p-s ]) ending=i }; for (j=beginning;j<=endin    g;j++) printf $j" ";printf "\n" }' .annex/file.c

Мой синтаксис кода неправильный, и я получаю кучу предупреждений:

awk: syntax error at source line 1
 context is
    {for(i=1;i<=NF;i++) {if ($i == "%") beginning=i; if($i == >>>  [ <<<
awk: illegal statement at source line 1
awk: illegal statement at source line 1`

Как я могу изменить этот код или использовать другой, чтобы удалить то, что находится между % и [A-G] || [a-g] || [m-n] || [p-s], когда % видели n раз?

1 Ответ

0 голосов
/ 25 января 2019

Попробуйте:

awk '{gsub(/%[^A-Ga-gm-np-s]+/, "%")} 1' .annex/file.c

Пример

Рассмотрим этот входной файл:

$ cat file.c
fprintf(stdout,"%-20s %0.h2d",a,b)
fprintf(stderr,"%.3f",c)

Давайте запустим нашу команду:

$ awk '{gsub(/%[^A-Ga-gm-np-s]+/, "%")} 1'  file.c 
fprintf(stdout,"%s %d",a,b)
fprintf(stderr,"%f",c)

Как это работает

gsub(/%[^A-Ga-gm-np-s]+/, "%") ищет любую строку, которая соответствует %, за которой следуют символы, которые не входят ни в один из диапазонов A-G, a-g, m-n или p-s, и заменяет ее просто % .

Замена только n-го вхождения

Если вы хотите заменить только n-е вхождение, попробуйте:

sed -E 'H;1h;$!d;x; s/%[^A-Ga-gm-np-s]+/%/'"$n"

Чтобы заменить, например, второе вхождение, используйте:

$ n=2; sed -E 'H;1h;$!d;x; s/%[^A-Ga-gm-np-s]+/%/'"$n"  file.c
fprintf(stdout,"%-20s %d",a,b)
fprintf(stderr,"%.3f",c)

Для замены третьего:

$ n=3; sed -E 'H;1h;$!d;x; s/%[^A-Ga-gm-np-s]+/%/'"$n"  file.c
fprintf(stdout,"%-20s %0.h2d",a,b)
fprintf(stderr,"%f",c)

Вы можете использовать любое значение для n, которое вам нравится.

Как это работает

  • -E говорит sed использовать расширенные регулярные выражения (тип по умолчанию для awk), а не базовые регулярные выражения.

  • H;1h;$!d;x; говорит sed читать файл в пространство шаблона.

    Эта серия команд читает весь файл. Вероятно, проще всего думать об этом как о идиоме. Если вы действительно хотите узнать подробности:

    • H - добавить текущую строку в качестве пробела
    • 1h - Если это первая строка, перезаписать пробел с этим
    • $!d - Если это не последняя строка, удалить пробел и перейти к следующей строке.
    • x - обмен удержанием и шаблоном для размещения всего файла шаблон пространства
  • 's/%[^A-Ga-gm-np-s]+/%/'"$n" указывает sed заменить n-ное вхождение шаблона.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...