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'
Но он возвращает исходную строку. Буду признателен, если вы дадите совет. Спасибо.
Похоже, вы немного запутались в том, как работает 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, могу порекомендовать отличный учебник
echo $s | sed -E 's/col(\(.*),(.*),(.*)\)/col\1,\2,t\3)/g'