Então, eu uso o 'sed' no linux há um tempo, mas tive um pouco de dificuldade ao tentar usá-lo no OSX, pois o 'POSIX sed' e o 'GNU sed' têm muitas pequenas diferenças. Atualmente, estou lutando para inserir uma linha de texto após um determinado número de linha. (neste caso, linha 4)
No linux, eu faria algo assim:
sed --in-place "4 a\ mode '0755'" file.txt
Então, no OSX, tentei o seguinte:
sed -i "" "4 a\ mode '0755'" file.txt
No entanto, isso continua me dando um erro de 'caracteres extras após \ no final de um comando'. Alguma idéia do que há de errado aqui? Eu tenho um erro de digitação? Ou não estou entendendo outra diferença entre as versões do sed?
Respostas:
Estritamente falando, a especificação POSIX para
sed
requer uma nova linha apósa\
:Isso faz com que escrever one-liners um pouco de dor, que é provavelmente a razão para o seguinte extensão GNU ao
a
,i
ec
comandos:Portanto, para ser portátil com sua
sed
sintaxe, você precisará incluir uma nova linha após oa\
procedimento. A maneira mais fácil é apenas inserir uma nova linha citada:(onde
$
e>
são prompts de shell). Se você achar que é uma dor,bash
[1] tem a$' '
sintaxe de aspas para inserir escapes no estilo C, então use[1] e mksh (r39b +) e algumas conchas de bourne que não sejam do tipo bash (por exemplo, / bin / sh no FreeBSD 9+)
fonte
Conforme descrito nesta resposta , é útil ao usar comandos sed como
i
ea
usar várias-e "..."
cláusulas. Cada uma dessas cláusulas será entendida como separada por novas linhas. Oi
ea
comandos são difíceis de usar em linha sed scripts de outra forma (eles são projetados para uso em um arquivo de script várias linhas sed solicitado usandosed -f file ...
). Parece que você não pode usar a nova linha implícita introduzida no final de uma-e
cláusula para separara\
a linha de texto a ser anexada. Mas você pode usá-lo para finalizar a linha de texto que será anexada.Nesse caso específico, o que você está tentando fazer pode ser realizado com uma única
-e ...
cláusula. Você apenas precisa usar oa
comando corretamente. Pelo padrão POSIX,a
precisa ser seguido por a e\
, em seguida, por uma nova linha; o restante da próxima linha será inserido (até que uma nova linha ou o final da-e
cláusula seja encontrada). Então você poderia fazer:fonte
O GNU sed parece ser muito mais usado do que o POSIX sed, com base em exemplos / tutoriais que já usei.
Eu descobri que é muito mais fácil instalar o GNU sed em qualquer máquina OSX que eu use. Se você estiver interessado, a melhor maneira de fazer isso é instalá-lo através do Homebrew .
Você pode apenas
$ brew install gnu-sed
, ou obter todos os utilitários comuns do GNU$ brew install coreutils
.Então, quando você se deparar com um problema de sintaxe com
date
ou em algum outro programa, você pode simplesmente usar a versão GNU. Eventualmente, eu apenas decidi que era mais fácil sempre usar as versões do GNU e colocá-las antes das versões do sistema no meuPATH
.fonte
O Perl não sofre dessas idiossincrasias GNU versus não GNU vs. "proprietárias" dependentes dessa plataforma. Você poderia fazer:
O
-n' option creates a loop that reads every line of the input file. Unlike its cousin
-p(not used here) it doesn't automatically print every line read. The
-iinvokes in-place replacement. The argument to
-i(viz. ".old") can be dropped or changed. It leaves a backup of the unmodified file. The -e
sinaliza o início do script.A
$.
indica a linha-número, começando com a linha-1. Assim, a linha de comando lê 'arquivo' e quando o número da linha é igual a 4, ela imprime essa linha seguida pelo que você deseja injetar.Gostaria de acrescentar que o Perl deve suas raízes a
sed
AWK e C, portanto a sintaxe para substituições simples etc. não é uma curva de aprendizado muito acentuada.fonte
perl -wlpi.old -e 'print "mode 0755" if $. == 5' file.txt
. O-p
switch funciona bem aqui (já que queremos imprimir todas as linhas); basta alterar a lógica de "impressão após a linha 4" para "impressão antes da linha 5". E a-l
opção faz com que "\ n" seja impresso automaticamente a cadaprint
, para que você não precise imprimi-lo.