У меня есть конфигурационный файл MRTG, содержащий строки, запускающиеся со слова "Target". Теперь в таких строках существует шаблон, запускающийся с символа "#" и заканчивающийся символом ":".
Демонстрационная строка могла быть похожей на них (отметьте два типа, но запустите/закончите, маркерами является все еще то же):
Target[192.168.0.1_Gi1_1]: #Gi1/1:public@192.168.0.1:::::2
Target[192.168.0.1_Gi1_31]: #Gi1/31:public@192.168.0.1:::::2
То, в чем я нуждаюсь, - чтобы sed нашел эти строки, и замените шаблон "#Gix/n:"
с "ifInErrors#Gix/n&ifInErrors#Gix/n:"
, где x =1-9
, n =1-48
.
Таким образом, две демонстрационных строки, показанные выше, были бы изменены к ним:
Target[192.168.0.1_Gi1_1]: ifInErrors#Gi1/1&ifInErrors#Gi1/1:public@192.168.0.1:::::2
Target[192.168.0.1_Gi1_31]: ifInErrors#Gi1/31&ifInErrors#Gi1/31:public@192.168.0.1:::::2
То, в чем Вы нуждаетесь, является группой фиксации - Вы получаете то, в чем Вы нуждаетесь в круглых скобках и можете сослаться на нее в замене. Как так:
grep ^[[:space:]]*Target file | sed 's/\(#Gi[1-9]\/[1-9][0-9]*\):/ifInErrors\1\&ifInErrors\1:/'
sed '/Target/s/\(#Gi[0-9]*_[0-9]*:\)/ifInErrors\1\&ifInErrors\1/' input.txt
sed '/Target/
эквивалентно grep Target | sed
, кроме него включает тот меньше процесса и один меньше канала.
s/
означает 'замену', наиболее распространенную команду sed; s/foo/bar/
заменил бы экземпляры строкового нечто с панелью, например.
/\(#Gi[0-9]*\/[0-9]*:\)
... скобки (которого нужно оставить с a \
) скажите sed отмечать все между ними как \1
(или \2 для второго отмеченного шаблона, \3 для третьего и т.д.). [0-9]*
означает 'любое количество чисел', и \/
завершенное /
(этого нужно оставить, потому что я использую /
как разделитель для sed; если Вы используете другой разделитель, как |
, затем Вы не должны были бы выходить/). Так #Gi[0-9]*\/[0-9]*:
шаблон, означающий, 'запускаются с #, сопровождаемого Gi, затем любое количество чисел, затем/, затем любое количество чисел, заканчивающихся':.
Так \1
соответствия безотносительно строки обнаруживаются шаблоном #Gi[0-9]*\/[0-9]*:
В первой строке, данной в вопросе,
Target[192.168.0.1_Gi1_1]: #Gi1/1:public@192.168.0.1:::::2
## The pattern #Gi[0-9]*\/[0-9]*: will match the substring
#Gi1/1:
... поэтому /ifInErrors\1\&ifInErrors\1/
говорит sed 'замена #Gi1/1:
с ifInErrors#Gi1/1:&ifInErrors#Gi1/1:
'.
Некоторый дополнительный материал: если бы Вы хотели просто распечатать строки, которые начинаются с 'Цели', делая sed замену, то Вы могли использовать эту строку:
sed -n '/Target/s/\(#Gi[0-9]*\/[0-9]*:\)/ifInErrors\1\&ifInErrors\1/p'
-n
говорит, что sed 'не печатают вывод', и p
в конце говорит, что он для печати строк sed продолжает работать.
Если бы Вы хотели перезаписать свой исходный файл, то Вы использовали бы это:
sed -i '/Target/s/\(#Gi[0-9]*\/[0-9]*:\)/ifInErrors\1\&ifInErrors\1/'