Вопрос или проблема
У меня есть строка
* {@jira: PIVOT-9968} Предоставить способ передачи `IMemoryCollector` в `IInternalMemoryMonitored#getMemoryStatistics(memoryCollector)` для предотвращения подсчета дублированных блоков.
Я хотел экранировать только первую строку, содержащую номер(ticket?) билета.
написать скрипт для добавления обратной косой черты
для моей предыдущей проблемы
* /{@jira: PIVOT-9968/} Предоставить способ передачи `IMemoryCollector` в `IInternalMemoryMonitored#getMemoryStatistics(memoryCollector)` для предотвращения подсчета дублированных блоков.
Я попробовал
mawk '/^\* {@jira: PIVOT/ { gsub(/[{} ]/,"\\\\&") } 1' changelog.md > tmp && mv tmp changelog.md
и получил
*\ \{@jira:\ PIVOT-8019\}\ Пивот:\ Добавил\ `MaxAppendOnlyFunction`\ и\ \ `MinAppendOnlyFunction`\ функции\ агрегации,\ которые\ не\ поддерживают\ разбиение,\ но\ могут\ быть\ использованы\ в\ агрегатном\ провайдере.
что мне нужно изменить? gsub?
В awk
sub()
заменит первое вхождение совпаденияgsub()
заменит все вхождения совпадения/[{} ]/
говорит, что нужно совпадение с любым из трех символов:{
,}
и
Если мы уберем пробел (оставив /{}/
):
$ awk '/^\* {@jira: PIVOT/ { gsub(/[{}]/,"\\\\&") } 1' changelog.md
* \{@jira: PIVOT-9968\} Предоставить способ передачи `IMemoryCollector` в `IInternalMemoryMonitored#getMemoryStatistics(memoryCollector)` для предотвращения подсчета дублированных блоков.
Предположим, что OP хочет использовать обратную косую черту в качестве символа экранирования и на строке будет только одна пара фигурных скобок, этого должно быть достаточно для выполнения требования OP.
Если в строке может быть несколько пар фигурных скобок …
$ cat changelog_2.md
* {@jira: PIVOT-1234} новая строка {с несколькими} наборами фигурных скобок {для демонстрации} целей
Запуск нового кода против этого файла ошибочно изменит все пары фигурных скобок:
$ awk '/^\* {@jira: PIVOT/ { gsub(/[{}]/,"\\\\&") } 1' changelog_2.md
* \{@jira: PIVOT-1234\} новая строка \{с несколькими\} наборами фигурных скобок \{для демонстрации\} целей
Чтобы ограничить замены только первой парой фигурных скобок, мы можем использовать пару вызовов sub()
, где каждый вызов заменяет первое вхождение одного символа; обратите внимание, что мы заменяем /[{}]/
на /{/
и /}/
, и поскольку мы знаем, какой символ мы будем сопоставлять, мы можем заменить \\&
на фактический символ (для небольшого упрощения кода):
$ awk '/^\* {@jira: PIVOT/ { sub(/{/,"\\{"); sub(/}/,"\\}") } 1' changelog_2.md
* \{@jira: PIVOT-1234\} новая строка {с несколькими} наборами фигурных скобок {для демонстрации} целей
Реализуя этот последний поочередный замену с помощью sed
:
$ sed 's/}/\\}/1; s/{/\\{/1' changelog.md changelog_2.md
* \{@jira: PIVOT-9968\} Предоставить способ передачи `IMemoryCollector` в `IInternalMemoryMonitored#getMemoryStatistics(memoryCollector)` для предотвращения подсчета дублированных блоков.
* \{@jira: PIVOT-1234\} новая строка {с несколькими} наборами фигурных скобок {для демонстрации} целей
Где:
- последующий
/1
говорит заменить первое вхождение - как и в методе
awk / sub()
, нам нужно выполнить две отдельные замены, чтобы соответствовать первой паре фигурных скобок
Ответ или решение
Как использовать awk
для экранирования первой пары фигурных скобок в строке
Вопрос, который вы подняли, касается использования команды awk
для экранирования только первой пары фигурных скобок в строках, содержащих информацию о тикетах, например, в формате {@jira: PIVOT-9968}
. Давайте разберем, как этого достичь с помощью awk
, и предоставим детальное объяснение для эффективного решения задачи.
Пример входных данных
Допустим, у вас есть строка, содержащая информацию о тикете:
* {@jira: PIVOT-9968} Provide a way to pass an `IMemoryCollector` to `IInternalMemoryMonitored#getMemoryStatistics(memoryCollector)` in order to prevent the count of duplicated blocks.
Согласно вашему запросу, вы хотите получить следующий результат:
* \{@jira: PIVOT-9968\} Provide a way to pass an `IMemoryCollector` to `IInternalMemoryMonitored#getMemoryStatistics(memoryCollector)` in order to prevent the count of duplicated blocks.
Решение с использованием awk
Для достижения этой цели предлагается следующий код на awk
:
awk '/^\* {@jira: PIVOT/ { sub(/{/,"\\{"); sub(/}/,"\\}") } 1' changelog.md > tmp && mv tmp changelog.md
Объяснение кода
- Шаблон:
'/^\* {@jira: PIVOT/'
проверяет, начинается ли строка с символа*
и содержит ли метку тикета, что позволяет применять замену только к нужным строкам. - Замена фигурных скобок:
sub(/{/,"\\{")
: заменяет первую открывающую фигурную скобку на экранированную\{
.sub(/}/,"\\}")
: заменяет первую закрывающую фигурную скобку на экранированную\}
.
Эти команды производят замены только для первой найденной пары фигурных скобок, что гарантирует, что другие пары в строке не будут затронуты.
- Вывод:
1
— это краткая форма дляprint
, которая выводит текущую строку.
Проблема с несколькими парами фигурных скобок
Если ваши строки могут содержать более одной пары фигурных скобок, например:
* {@jira: PIVOT-1234} new line {with several} sets of braces {for demonstration} purposes
Ваш первоначальный код вызовет нежелательные замены всех фигурных скобок. Чтобы избежать этого, используйте описанный выше код с sub()
, как в примере, чтобы экранировать только первую пару каждого вхождения тикета.
Альтернативный способ с использованием sed
Как альтернатива awk
, можно использовать sed
для достижения аналогичного результата:
sed 's/}/\\}/1; s/{/\\{/1' changelog.md > tmp && mv tmp changelog.md
Объяснение sed
s/}/\\}/1
: заменяет первую закрывающую фигурную скобку в строке.s/{/\\{/1
: заменяет первую открывающую фигурную скобку в строке.- Использование
1
в конце каждой замены гарантирует, что только первое вхождение будет изменено.
Заключение
Вам удалось выяснить, как использовать awk
для экранирования первой пары фигурных скобок в строках, связанными с тикетами. Этот метод эффективно решает проблему, избегая влияния на другие части строки. Теперь вы можете применять этот подход для обработки ваших файлов в командной строке, улучшая итоговые результаты работы со строками, содержащими спецификации тикетов.