Рейтинг:1

Sed для замены подстроки внутри строки шаблоном

флаг in

Я пытаюсь заменить часть шаблона, например, если у меня есть столбец (3, Б, 14), после применения сед команда, я хотел бы получить столбец(3,B,t14) который добавляет т символ в третий параметр шаблона.

Я пытаюсь с:

с = "кол (3, Б, 14)"
эхо $s | sed 's/col([0-9],[AZ],[0-9])/col([0-9],[AZ],t[0-9])/g'

Но он возвращает исходную строку. Я был бы признателен, если бы вы могли дать несколько советов. Спасибо.

FedKad avatar
флаг cn
Вы должны использовать обратные ссылки в строке замены: https://www.gnu.org/software/sed/manual/html_node/Back_002dreferences-and-Subexpressions.html
CGeorgi avatar
флаг in
Спасибо, FedonKadifeli, да, я последовал вашему совету и нашел решение: echo $s | sed -E 's/col(\(.*),(.*),(.*)\)/col\1,\2,t\3)/g', используя обратные ссылки, как вы предлагаете. Спасибо большое.
Рейтинг:4
флаг in

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

с = "столб (3, B, 14)"; эхо $s | sed 's/\(col([0-9],[A-Z],\)/\1t/g'

Объяснение

Здесь есть пара проблем. Во-первых, вам нужна точка с запятой после определение вашей переменной 's', прежде чем повторять ее.

с = "столб (3, B, 14)"; эхо $s 

Затем подстановка sed работает с помощью «s/pattern/replacement/», где «pattern» — это регулярное выражение, а где "замена" - нет. То есть положить что-то например «[0-9]» в замене не будет представлять никакой цифры, а вместо этого представляют пять символов: [, 0, -, 9, и ]. Так же в конец означает продолжать применять замену к строке для каждого совпадения шаблон (поэтому, если бы у вас была линия вроде эхо привет мир | sed 's/o/z/g' тогда вывод будет «hellz wzrld». Тогда как эхо привет мир | sed 's/o/z/' дал бы "адский мир")

Итак, давайте удалим вашу замену на данный момент:

с = "столб (3, B, 14)"; эхо $s | sed 's/col([0-9],[AZ],[0-9])/замена/g'

Обратив внимание на шаблон регулярного выражения, который вы использовали, он говорит: строка типа 'col(<одна цифра>,<заглавная буква>,<одна цифра>)' - уведомление что последний [0-9] часть не будет соответствовать «14», так как это две цифры и т.д. ваш шаблон будет соответствовать, скажем, «col (3, B, 1)», но не будет соответствовать «col (3, B14)». К соответствуют одной или нескольким цифрам, вы можете использовать [0-9][0-9]*:

Чтобы сделать замену так, как вы хотите, лучше всего использовать «захват группа'. Группы захвата «запоминают» часть совпадения для последующего использования. Вы положили \( и \) вокруг той части шаблона, которую вы хотите запомнить и использовать \1 к обратитесь к нему позже:

с = "столб (3, B, 14)"; эхо $s | sed 's/\(col([0-9],[A-Z],\)/\1replacement/g'

Это будет соответствовать 'col(<одиночная цифра>,<заглавная буква>,' - так что до и включая точку, где вы хотите добавить «t». Все эти согласованные вещи будут вернуть взамен(\1), за которым следует любой текст, который вы добавляете (в этом случае мы добавляем буквальный текст «замена»). Любой оставшийся текст не сопоставленные во входных данных не будут затронуты. Выше будет вывод:

столбец(3,B,1замена4)

Итак, если мы теперь поместим 't' в строку замены:

с = "столб (3, B, 14)"; эхо $s | sed 's/\(col([0-9],[A-Z],\)/\1t/g'

Мы получили:

столбец(3,B,t14)

Если вы хотите хорошо изучить sed, я могу порекомендовать отличный руководство.

CGeorgi avatar
флаг in
Большое спасибо mattb за подробное объяснение. Я обязательно прочитаю учебник по sed.
Рейтинг:-2
флаг in

эхо $s | sed -E 's/col(\(.*),(.*),(.*)\)/col\1,\2,t\3)/g'

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.