$ (echo hello; echo there) | sed ':a;$!N;s/\n/string/;ta'
hellostringthere
O sed
comando acima substitui o novo caractere de linha pela string "string". Mas não sei o significado das :a;$!N;s/\n/string/;ta
aspas simples. Eu sei a parte do meio s/\n/string/
. Mas não sei a função da primeira ( :a;$!N;
) e da última ( ta
) parte.
sed
text-processing
Avinash Raj
fonte
fonte
Respostas:
Estes são os
sed
comandos , reconhecidamente enigmáticos . Especificamente (deman sed
):Portanto, o script que você postou pode ser dividido em (espaços adicionados para facilitar a leitura):
Basicamente, o que isso está fazendo pode ser escrito em pseudocódigo como
Você pode entender isso um pouco melhor com um exemplo de entrada mais complexo:
Não sei ao certo por que isso
!$
é necessário. Tanto quanto eu posso dizer, você pode obter a mesma saída comfonte
$!
não!$
. No entanto, também pode ser!N
e não$!
.!N
ou a$!
. Portanto, continuo pensando que a última linha é nova linha ou EOF.$!
como um endereço 'range' com um operador de complemento postfix - assim$!N
(emN
qualquer lugar, exceto no endereço$
), é realmente a mesma sintaxe de algo comom,n!d
(exclua tudo, exceto as linhasm
paran
).:
é analógico degoto
etiqueta, e de fato:
costumava ser Goto rótulo em Thompson shell, então seria familiar para as pessoas de volta ao dia usando tanto sed e Thompson shellEu postar esta resposta desde que eu vejo um monte de confusão sobre por que a última linha é excluído durante a execução
N
(através da linha de cadeia de endereçamento$!
) e porque o OP estava confuso sobre o significado:a;$!N;
em um comando sed , não só na a um específico ele postou .Bem, o benefício de usar em
$!N
vez deN
não é evidente nos exemplos propostos (pelo OP e pelo @terdon), já que nenhum comando "importante" (continue lendo) é executado na última linha após oN
comando. (De fato, o resultado é o mesmo se alguém retirar esse endereço da linha.)Em um exemplo mais complexo (por exemplo, substitua
this sentence
em um arquivo, com as duas palavras aparecendo algumas vezes em uma linha e outras vezes em duas linhas), excluir a última linha doN
comando pode ser crucial! Se a última linha não for excluída, ao ser executadaN
, elased
bateEOF
e sai imediatamente, impedindo que todos os comandos subseqüentes (também os comandos de ramificação, ou seja,t
eb
) sejam executados.Nos exemplos simplistas mostrados, podemos remover com segurança
$!
e deixar desed
executarN
e retornar com falha, pois os
comando abortado não faria nada se fosse executado, pois não há\n
como corresponder.fonte