Как заменить нетипичный шаблон в текстовом файле с помощью sed

У меня есть конфигурационный файл 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
1
задан 31 January 2013 в 08:26

2 ответа

То, в чем Вы нуждаетесь, является группой фиксации - Вы получаете то, в чем Вы нуждаетесь в круглых скобках и можете сослаться на нее в замене. Как так:

 grep ^[[:space:]]*Target file | sed 's/\(#Gi[1-9]\/[1-9][0-9]*\):/ifInErrors\1\&ifInErrors\1:/'
1
ответ дан 31 January 2013 в 08:26
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/'
1
ответ дан 31 January 2013 в 08:26

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

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