Por alguma razão, não consigo encontrar uma resposta direta para isso e estou com um pouco de dificuldade no momento. Como eu inseri uma linha de texto de escolha após a primeira linha que corresponde a uma sequência específica usando o sed
comando Eu tenho ...
CLIENTSCRIPT="foo"
CLIENTFILE="bar"
E eu quero inserir uma linha após a CLIENTSCRIPT=
linha, resultando em ...
CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"
sed
. Essa não é ased
sintaxe padrão e não funcionará com nenhuma outrased
implementação.Observe a
sed
sintaxe padrão (como no POSIX, suportada por todas assed
implementações em conformidade (GNU, OS / X, BSD, Solaris ...)):Ou em uma linha:
(
-e
xpressions (e o conteúdo de-f
iles) são associados a novas linhas para compor assed
interpretações do script sed ).A
-i
opção para edição in-loco também é uma extensão GNU, algumas outras implementações (como o FreeBSD) suportam-i ''
isso.Como alternativa, para portabilidade, você pode usar
perl
:Ou você pode usar
ed
ouex
:fonte
sed -e '/CLIENTSCRIPT=/a\' -e 'CLIENTSCRIPT2="hello"' file
escapa da citação no final do primeiro parâmetro e quebra o comando.csh
ourc
família,'...'
são citações fortes dentro das quais a barra invertida não é especial. A única exceção que eu sei é ofish
shell.sed
não é compatível com POSIX aqui. Isso faz com que minha afirmação sobre ele seja portátil seja incorreta (para a variante de uma linha). Pedirei confirmação ao grupo aberto se é de fato uma não conformidade ou uma interpretação incorreta do padrão da minha parte.Um compatível com POSIX usando o
s
comando:fonte
sed -e '/.../s/$/\' -e 'CLI.../'
que evitaria problemas com linhas que contêm seqüências de bytes que não formam caracteres válidos.Comando Sed que funciona no MacOS (pelo menos, no OS 10) e no Unix (ou seja, não requer gnu sed como o de Gilles (atualmente aceito)):
Isso funciona no bash e talvez em outros shells que também conhecem o estilo de cotação de avaliação $ '\ n'. Tudo pode estar em uma linha e funcionar em comandos / POSIX sed mais antigos. Se houver várias linhas correspondentes ao CLIENTSCRIPT = "foo" (ou seu equivalente) e você desejar adicionar apenas a linha extra na primeira vez, poderá refazê-la da seguinte maneira:
(isso cria um loop após o código de inserção de linha que apenas percorre o restante do arquivo, nunca voltando ao primeiro comando sed novamente).
Você pode notar que adicionei um '^ *' ao padrão correspondente, caso essa linha apareça em um comentário, digamos, ou seja recuada. Não é 100% perfeito, mas cobre algumas outras situações que provavelmente serão comuns. Ajuste conforme necessário ...
Essas duas soluções também contornam o problema (para a solução genérica de adicionar uma linha) de que, se a nova linha inserida contiver barras invertidas ou e comercial sem escape, elas serão interpretadas pelo sed e provavelmente não sairão da mesma forma, como
\n
são - por exemplo.\0
seria a primeira linha correspondente. Especialmente útil se você estiver adicionando uma linha que vem de uma variável em que você teria que escapar de tudo primeiro usando $ {var //} antes ou outra instrução sed etc.Essa solução é um pouco menos confusa nos scripts (que citar e \ n não é fácil de ler), quando você não deseja colocar o texto de substituição para o comando a no início de uma linha, digamos, em uma função com linhas recuadas. Eu aproveitei que $ '\ n' é avaliado como uma nova linha pelo shell, não está nos valores regulares de aspas simples '\ n'.
Está ficando longo o suficiente, mas acho que o perl / awk pode ganhar devido a ser mais legível.
fonte
s/CLIENTSCRIPT="foo"/&\
[Enter]CLIENTSCRIPT2="hello"/
. A barra invertida deve ser o último caractere da linha (sem espaço em branco depois dela), ao contrário da aparência neste comentário.s///
, assim como as dos comandosa
e,i
podem ser "escapadas", usando o mesmo método que descrevi no meu comentário acima.Talvez um pouco tarde para postar uma resposta para isso, mas achei algumas das soluções acima um pouco complicadas.
Eu tentei a substituição simples de string no sed e funcionou:
O sinal de & reflete a sequência correspondente e, em seguida, você adiciona \ n e a nova linha.
Como mencionado, se você quiser fazer isso no local:
Outra coisa. Você pode combinar usando uma expressão:
Espero que isso ajude alguém
fonte
\n
na cadeia de substituição. Plain vanilla (POSIX)sed
que não entendem\n
no texto de substituição, no entanto, assim que este não irá funcionar no BSD ou MacOS-a menos que você tenha instalado o GNU sed de alguma forma. Com o vanilla sed, você pode incorporar novas linhas "escapando" delas, ou seja, encerrando a linha com uma barra invertida e pressionando [Enter] ( referência , sob o cabeçalho[2addr]s/BRE/replacement/flags
). Isso significa que o seu comando sed precisa abranger várias linhas no terminal.A variante awk:
fonte
1;
, consulte Por que "1" no awk imprime a linha atual?Eu tive uma tarefa semelhante e não foi capaz de obter a solução perl acima para funcionar.
Aqui está a minha solução:
perl -i -pe "BEGIN{undef $/;} s/^\[mysqld\]$/[mysqld]\n\ncollation-server = utf8_unicode_ci\n/sgm" /etc/mysql/my.cnf
Explicação:
Usa uma expressão regular para procurar uma linha no meu arquivo /etc/mysql/my.cnf que continha apenas
[mysqld]
e a substituiu por[mysqld] collation-server = utf8_unicode_ci
adicionando efetivamente a
collation-server = utf8_unicode_ci
linha após a linha que contém[mysqld]
.fonte
Eu tive que fazer isso recentemente também para sistemas operacionais Mac e Linux e, depois de navegar por várias postagens e experimentar muitas coisas, em minha opinião particular, nunca cheguei aonde queria: onde é simples o suficiente para entender a solução usando soluções conhecidas. e comandos padrão com padrões simples, um liner, portátil, expansível para adicionar mais restrições. Então tentei olhar para ele com uma perspectiva diferente; foi quando percebi que poderia ficar sem a opção "one liner" se um "2 liner" atender ao restante dos meus critérios. No final, eu vim com esta solução que eu gosto que funciona tanto no Ubuntu quanto no Mac, que eu queria compartilhar com todos:
No primeiro comando, o grep procura números de linhas que contêm "foo", cut / head seleciona a 1ª ocorrência, e a operação aritmética aumenta esse número da linha da primeira ocorrência em 1, desde que desejo inserir após a ocorrência. No segundo comando, é uma edição de arquivo no local, "i", para inserção: um ansi-c citando uma nova linha, "bar", depois outra nova linha. O resultado é adicionar uma nova linha contendo "bar" após a linha "foo". Cada um desses 2 comandos pode ser expandido para operações e correspondências mais complexas.
fonte