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

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

Я пытаюсь использовать:

s="col(3,B,14)"
echo $s | sed 's/col([0-9],[A-Z],[0-9])/col([0-9],[A-Z],t[0-9])/g'

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

0
задан 6 June 2021 в 11:54

2 ответа

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

s="col(3,B,14)"; echo $s | sed 's/\(col([0-9],[A-Z],\)/\1t/g'

Объяснение

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

s="col(3,B,14)"; echo $s 

Далее, подстановка в sed работает по принципу 's/pattern/replacement/' - где 'pattern' является регулярное выражение, а 'замена' - нет. То есть, вставляя что-то типа '[0-9]' в замену не будет представлять никакую цифру, а вместо этого будет представлять пять символов: '[', '0', '-', '9' и ']'. Кроме того, /g в в конце означает, что подстановка будет применяться к строке при каждом совпадении с шаблона (поэтому если у вас была строка вида echo hello world | sed 's/o/z/g', тогда результатом будет 'hellz wzrld'. В то время как echo hello world | sed 's/o/z/' даст 'hellz world')

Так что давайте пока уберем вашу замену:

s="col(3,B,14)"; echo $s | sed 's/col([0-9],[A-Z],[0-9])/replacement/g'

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

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

s="col(3,B,14)"; echo $s | sed 's/\(col([0-9],[A-Z],\)/\1replacement/g'

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

col(3,B,1replacement4)

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

s="col(3,B,14)"; echo $s | sed 's/\(col([0-9],[A-Z],\)/\1t/g'

Мы получим:

col(3,B,t14)

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

3
ответ дан 28 July 2021 в 11:31

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

-1
ответ дан 28 July 2021 в 11:31

Другие вопросы по тегам:

Похожие вопросы: