Como substituir a linha pelo conteúdo do arquivo e pelo conteúdo com algum texto?

3

Gostaria de combinar certificados VPN em um único arquivo. Este é um arquivo de modelo:

# some unrelated stuff 

ca ca.crt

# other unrelated stuff

E eu quero substituir a linha ca ca.crt pelo seguinte conteúdo:

<ca>
# ca.crt contents
</ca>

Eu tentei este script:

cat client-template.ovpn | 
sed -e 's/ca ca.crt/<ca>\n<\/ca>/' | 
sed -e '/<ca>/r ca.crt'

Embora este script funcione bem, eu tenho que colar dois outros arquivos junto com ca.crt , e eu gostaria de saber, existe algum comando, que permite combinar os comandos s e r juntos? / p>

Estou usando sed , mas as respostas com outras ferramentas Unix são bem-vindas.

    
por soon 20.09.2015 / 10:40

7 respostas

3

Com o bom e velho ed :

ed -s client-template.ovpn <<\IN
/ca ca.crt/s//<ca>\
<\/ca>/
- r ca.crt
/cert client.crt/s//<cert>\
<\/cert>/
- r client.crt
/key client.key/s//<key>\
<\/key>/
- r client.key
,p
q
IN

isso muda uma linha como

tag tag.extension

para

<tag>
</tag>

e, em seguida, r está no conteúdo de tag.extension antes ( - ) da linha de marcação de fechamento (ou seja, a linha atual após a substituição). Substitua ,p por w para realmente gravar as alterações no arquivo de modelo (ou use w somefile para salvar as alterações em outro arquivo). Tenha em mente que ed terá erro se um padrão não for encontrado.

Com sed você pode combinar r com a ( a , como r , não opera no espaço padrão - ao contrário de s , o que faz):

sed '
/ca ca.crt/{
s//<ca>/
r ca.crt
a\
</ca>
}
/cert client.crt/{
s//<cert>/
r client.crt
a\
</cert>
}
/key client.key/{
s//<key>/
r client.key
a\
</key>
}
' client-template.ovpn
    
por 20.09.2015 / 20:17
3

Com o GNU sed , supondo que esses nomes não contenham caracteres de aspas simples, você poderia fazer:

sed "s|^ca \(.*\)|echo '<ca>'; cat ''; echo '</ca>'|e"
    
por 20.09.2015 / 22:22
1

Para este problema, eu não usaria o sed, mas usaria a abordagem mencionada neste tópico - link

A ideia é usar o próprio bash como a linguagem de templates, para que você possa facilmente fazer coisas como incluir arquivos no seu template.

Seu modelo torna-se assim um script bash que você executa para gerar seu arquivo. Aplicá-lo ao seu problema pode ser algo assim:

make-client.sh:

#!/bin/bash

cat <<-EOF
# some unrelated stuff

<ca>
$(cat ca.crt)
</ca>

<other>
$(cat other.file)
</other>

# other unrelated stuff
EOF

Uso da linha de comando:

$ make-client.sh > client.ovpn
    
por 20.09.2015 / 11:42
1
sed -e 's/ca cert.crt/<ca>/' -e 'T' -e 'r cert.crt' -e 'a\</ca>' client-template.ovpn
    
por 20.09.2015 / 10:52
0

Se eu entendi sua pergunta corretamente, parece ser possível usar uma combinação de r e D , por exemplo.

sed '/^ca ca.crt/ {
r new-content-file
D
}' client-template.ovpn
    
por 20.09.2015 / 14:35
0

Se bem entendi, você gostaria de apoiar um nome de arquivo variável após a palavra ca . Enquanto você pode fazê-lo com o GNU sed , eu usaria o awk (ou o Perl).

awk '
    $1 == "ca" && NR == 2 { # if the current line consists of two words, the first of which is "ca"
        print "<ca>";
        while (getline <$2) print;
        close($2);
        print "</ca>";
    }
    1    # print anything else unmodified
'client-template.ovpn
    
por 20.09.2015 / 22:47
0
sed '5 i\
<ca>
     5 r tempo.csv
     5 a\
</ca>
     5 d' client-template.ovpn 
  • a ordem de ação é importante (especialmente a d como última ação
  • a nova linha é representada por um final \ em i nsert e a ppend action
por 21.09.2015 / 10:04