O que você precisa é de um grupo de captura - você captura o que precisa entre parênteses e pode referenciá-lo na substituição. Assim:
grep ^[[:space:]]*Target file | sed 's/\(#Gi[1-9]\/[1-9][0-9]*\):/ifInErrors\&ifInErrors:/'
Eu tenho um arquivo de configuração MRTG contendo linhas começando com a palavra "Target". Agora, em tais linhas, há um padrão começando com o caractere "#" e terminando com o caractere ":".
Uma linha de amostra pode ter essa aparência (observe dois tipos, mas os marcadores de início / fim ainda são os mesmos):
Target[192.168.0.1_Gi1_1]: #Gi1/1:[email protected]:::::2
Target[192.168.0.1_Gi1_31]: #Gi1/31:[email protected]:::::2
O que eu preciso é que o sed encontre essas linhas e substitua o padrão "#Gix/n:"
por
"ifInErrors#Gix/n&ifInErrors#Gix/n:"
, onde x = 1-9
, n = 1-48
.
Assim, as duas linhas de amostra mostradas acima seriam modificadas para estas:
Target[192.168.0.1_Gi1_1]: ifInErrors#Gi1/1&ifInErrors#Gi1/1:[email protected]:::::2
Target[192.168.0.1_Gi1_31]: ifInErrors#Gi1/31&ifInErrors#Gi1/31:[email protected]:::::2
O que você precisa é de um grupo de captura - você captura o que precisa entre parênteses e pode referenciá-lo na substituição. Assim:
grep ^[[:space:]]*Target file | sed 's/\(#Gi[1-9]\/[1-9][0-9]*\):/ifInErrors\&ifInErrors:/'
sed '/Target/s/\(#Gi[0-9]*_[0-9]*:\)/ifInErrors\&ifInErrors/' input.txt
sed '/Target/
é equivalente a grep Target | sed
, exceto que envolve menos um processo & amp; um tubo a menos.
s/
significa 'substituição', o comando sed mais comum; s/foo/bar/
substitui instâncias da string foo por bar , por exemplo.
/\(#Gi[0-9]*\/[0-9]*:\)
... os colchetes (que precisam ser escapados com \
) dizem ao sed para marcar tudo entre eles como (ou \ 2 para o segundo padrão marcado, \ 3 para o terceiro etc. ).
[0-9]*
significa 'qualquer número de números' e \/
é um escape /
(ele precisa ser de escape porque estou usando /
como o separador para sed; se você usar outro separador, como |
, então você não precisaria escapar do /). Então, #Gi[0-9]*\/[0-9]*:
é um padrão que significa 'comece com #, seguido por Gi, depois qualquer número de números, então /, então qualquer número de números, terminando com:'.
Então, corresponde a qualquer string detectada pelo padrão
#Gi[0-9]*\/[0-9]*:
Na primeira string dada na pergunta,
Target[192.168.0.1_Gi1_1]: #Gi1/1:[email protected]:::::2
## The pattern #Gi[0-9]*\/[0-9]*: will match the substring
#Gi1/1:
... portanto, /ifInErrors\&ifInErrors/
informa ao sed 'substituir #Gi1/1:
por ifInErrors#Gi1/1:&ifInErrors#Gi1/1:
'.
Algumas coisas extras: se você quiser apenas imprimir as linhas que começam com 'Target', fazendo a substituição do sed, você pode usar esta linha:
sed -n '/Target/s/\(#Gi[0-9]*\/[0-9]*:\)/ifInErrors\&ifInErrors/p'
-n
diz ao sed 'não imprime a saída', e o p
no final diz para imprimir as linhas em que o sed está trabalhando.
Se você quisesse sobrescrever seu arquivo original, você usaria isso:
sed -i '/Target/s/\(#Gi[0-9]*\/[0-9]*:\)/ifInErrors\&ifInErrors/'