Как правильно использовать обратную ссылку команды замены sed с учетом специального регулярного выражения - PullRequest
0 голосов
/ 30 декабря 2018

Я изучаю команду sed s / regexp / replace / для linux.

Есть некоторые цифры из phone.txt

(555)555-1212
(555)555-1213
(555)555-1214
(666)555-1215
(777)555-1217

Я хотел бы использовать регулярное выражение(который я проверил на https://www.freeformatter.com/regex-tester.html)

 (\(555\))(.*-)(.*$)

, чтобы соответствовать числам, которые начинаются с (555). И затем я хочу вывод этих трех частей этого совпавшего числа как: (пример для числа (555) 555-1212)

Area code: (555) Second: 555- Third: 1212

Я попробовал следующую команду:

cat phone.txt | sed 's/\(\\\(555\\\)\)\(.*-\)\(.*$)/Area code: \1 Second: \2 Third: \3/'

Но система выдала мне:

sed: -e expression #1, char 66: Unmatched ( or \(

Общая команда для всехчисла были:

cat phone.txt | sed 's/\(.*)\)\(.*-\)\(.*$\)/Area code: \1 Second: \2 Third: \3/'

Источник: https://www.tutorialspoint.com/unix/unix-regular-expressions.htm

Но я просто хочу выполнить sed для чисел, которые начинаются с (555) , и добавить их в выводчерез обратная ссылка .

Не могли бы вы сказать, как правильно написать эту специальную команду?

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

Вы можете обобщить, используя форматирование, включенное в строку, чтобы выбрать первое 555, второе 555 и третье 1212, не ограничивая себя каким-либо конкретным префиксом в форме замены s/find/replace/ sed.Затем вы можете ограничить при необходимости, добавив условие сопоставления перед заменой, в которое вы введете 555 или 666 и т. Д.

Чтобы включить сопоставление с шаблоном вместе с заменой, вы используетеследующая форма:

sed '/pattern/s/find/replace/'

Чтобы соответствие шаблону подавляло вывод для всех строк, кроме тех, которые соответствуют шаблону, вы передаете опцию -n для подавления печати пространства шаблона и включаете p вконец замещающей формы, чтобы явно напечатать те строки, которые соответствуют, например,

sed -n '/pattern/s/find/replace/p'

Теперь давайте обратимся к вашей проблеме под рукой.Чтобы ограничить переформатированный вывод только теми строками, которые начинаются с (555), вы должны сделать:

$ sed -n '/^(555)/s/^(\([^)]*\))\([^-]*\)-\(.*\)$/Area code: (\1) Second: \2- Third: \3/p' file
Area code: (555) Second: 555- Third: 1212
Area code: (555) Second: 555- Third: 1213
Area code: (555) Second: 555- Third: 1214

( примечание: обратные ссылки захватывают только цифры, а не (..) или '-')

Чтобы переформатировать все строки, вы должны удалить -n и /pattern/ вместе с окончательным p, используя только базовую форму sed 's/find/replace/, например,

$ sed 's/^(\([^)]*\))\([^-]*\)-\(.*\)$/Area code: (\1) Second: \2- Third: \3/' file
Area code: (555) Second: 555- Third: 1212
Area code: (555) Second: 555- Third: 1213
Area code: (555) Second: 555- Third: 1214
Area code: (666) Second: 555- Third: 1215
Area code: (777) Second: 555- Third: 1217

Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.

0 голосов
/ 30 декабря 2018

Ypu использует синтаксис POSIX BRE в вашей команде sed, и в таких шаблонах неэкранированные скобки соответствуют буквальным скобкам.Избегающие скобки определяют группы захвата.

Вы можете использовать

sed -E 's/(\(555\))(.*-)(.*)/Area code: \1 Second: \2 Third: \3/'

См. онлайн-демонстрацию

Буквальные скобки в синтаксисе POSIX ERE (доступно с-E опция) экранируются, как и во всех распространенных онлайн-тестерах регулярных выражений, а неэкранированные скобки определяют группы захвата.

...