sed - chamando uma variável de um arquivo com várias linhas

0

Sou novo em programação (/ scripting?), pois isso ficará claro.

Propósito:

Tentar criar um script reutilizável automatiza a instalação / configuração de novas instâncias do linux .... pois continuo quebrando-as. Neste caso, estou mexendo com o /etc/pam.d/sshd

E aprender ... sed definitivamente está me fazendo aprender sobre citações, pausas e todos os conceitos básicos.

Eu tenho isso funcionando como você pode ver, mas tenho algumas perguntas (e eu suspeito que alguém vai apontar como este método é frágil)

Pergunta 1-2)

Arquivo variável - sendo passado como um argumento para o sedinsert.sh

sedfind="# Standard Un\*x authentication."
#sedfind=".* Standard Un\*x authentication"
sedinsert="I am a \nmulti line variable \nand I kind of work"
sedfile=sshd

Estou tentando fazer com que isso faça o trabalho pesado, ou seja, eu vou escapar de qualquer caractere necessário no comando sed ou usar curingas aqui, então eu só tenho que mudar o arquivo variável em atualizações uma vez e é, para mim menos, um pouco mais limpo.

Ele também ajuda imensamente a minha compreensão, pois posso ver facilmente como as alterações afetam a saída / resultados.

Q1. Estou certo com minhas citações e novas linhas aqui. Parece funcionar, mas existe outro caminho? Eu tenho uma sensação horrível que eu vou bater em um personagem em breve que vai quebrar isso - qualquer exemplo?

Q2. É possível dividir as variáveis em várias linhas para facilitar o trabalho com este arquivo, quando necessário, (por exemplo, semelhante ao uso de \ no final da linha) - tendo em mente o fornecimento e a sed. Talvez outro comando dentro do roteiro para lidar com isso? (Grep? Ou outro sed ?.

Pergunta 2

sedinsert.sh

set -x
source $1
sed -i "\|$sedfind|a\ \n$sedinsert" $sedfile

Estou tentando manter isso o mais limpo possível e também não usar aspas ao redor das variáveis. Eu tenho atualmente um outro para substituir no momento, mas eu provavelmente vou olhar passando o comando como uma variável próxima

Não estou absolutamente comprometida com essa ideia, mas espero que as razões façam sentido ... ou seja, isso será usado para alterar todos os tipos de arquivos com caracteres "difíceis", por exemplo, @ # "etc

Q. Por causa disso, estou tendo que colocar a primeira nova linha no próprio comando (| a \ / n ....). Haveria alguma maneira de colocar isso na própria variável caso eu não queira / queira incluir várias linhas em branco?

Pergunta 3

É bom em sed que você pode definir o delimitador padrão (termo correto?) de \ para | como eu tenho aqui.

Mas toda vez que eu acho que encontrei um bom para usar, eu acho que está incluído no próximo arquivo que eu vejo

Q. Existe algum delimitador obscuro sugerido / padrão para usar que raramente é usado em outro lugar - então eu não continuo encontrando em um arquivo, por exemplo, algum personagem russo (desculpas para qualquer um russo) ao invés de # |, etc.

Estou um pouco confuso porque todo mundo usa os mais comuns, que parecem causar às pessoas todos os tipos de confusão (por exemplo, / em caminhos de arquivo) passando por outras respostas

Pergunta 4: Agora, como eu deveria estar realmente fazendo tudo isso?

Algumas linhas de pam.sshd como exemplo

# PAM configuration for the Secure Shell service

# Standard Un*x authentication.
@include common-auth

# Disallow non-root logins when /etc/nologin exists.
account    required     pam_nologin.so

Desculpe pela duração - achei que valeria a pena explicar todo o processo

    
por beardedfool 11.07.2017 / 19:51

1 resposta

1

Como sedinsert.sh contém o comando source , presumo que você use o bash.

Pergunta 1-2)

Q1.

Você está certo.

Q2.

Na verdade, um pode ter uma variável com o símbolo de nova linha:

sedinsert="I am a 
multi line variable 
and I kind of work"

O fornecimento será OK na medida em que arquivo variável é um script bash válido.

Para seus objetivos, você pode ter essa variável (com barras invertidas adicionais que precedem cada nova linha):

sedinsert="I am a \
multi line variable \
and I kind of work"

As barras invertidas são necessárias para usar com o sed. Agora você pode usar seu comando sem alterações:

sed -i "\|$sedfind|a\ \n$sedinsert" $sedfile

Questão 2

O comando sed a \ deve ser usado com nova linha como aqui:

sed -i "\|$sedfind|a \
$sedinsert" $sedfile

Por exemplo, o comando

sed "/ping/a \
pong" -i file.txt

Adicionará uma string pong após cada string que contiver "ping" de substring (sem novas linhas e espaços extras).

Se você não gostar da aparência, poderá usar o mecanismo $'word' para representar a nova linha:

sed "/ping/a \"$'\n'"pong" -i file.txt

ou

newline=$'\n'
sed "/ping/a \${newline}pong" -i file.txt

Pergunta 3

Em primeiro lugar, todos os símbolos vão até padrão (por exemplo, valor de sedfind ) não o contém. O conteúdo do arquivo $sedfile não importa. Delimitador é usado apenas para indicação do fim do padrão. Em segundo lugar, se for necessário usar um caractere delimitador no padrão, é possível escapar de todas as ocorrências com barra invertida:

sed "\|bar\|bar| a \
foo-foo"

adicionará uma string foo-foo após cada string que contiver bar|bar

Is there some suggested/ standard obscure delimiter to use that's rarely used elsewhere?

Eu não sei nada sobre isso.

A propósito, minha versão do sed não aceita caracteres russos como delimitador (mensagem de erro delimiter character is not a single-byte character ).

Resumo

Agora você pode usar este arquivo variável :

sedfind="# Standard Un\*x authentication."  # all occurrences of symbol '|' must be escaped by backslash as far as '|' is sed pattern delimiter
#sedfind=".* Standard Un\*x authentication"
sedinsert="I am a \
multi line variable \
and I kind of work"
sedfile=sshd

E este sedinsert.sh :

set -x
source $1
sed -i "\|$sedfind|a \
$sedinsert" $sedfile

É melhor cercar as variáveis com aspas duplas (caso contrário, o script irá travar em nomes de arquivos com símbolos especiais):

set -x
source "$1"
sed -i "\|$sedfind|a \
$sedinsert" "$sedfile"

Este script adicionará a (s) sequência (s) $sedinsert após cada linha do arquivo $sedfile que corresponde ao padrão $sedfind .

Bom tutorial sobre citações, expressões regulares e scripts sed, pode ser útil: link

    
por 28.08.2017 / 00:06