root@u1804:~# sed --version
sed (GNU sed) 4.5
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Jay Fenlason, Tom Lord, Ken Pizzini,
and Paolo Bonzini.
GNU sed home page: <https://www.gnu.org/software/sed/>.
General help using GNU software: <https://www.gnu.org/gethelp/>.
E-mail bug reports to: <[email protected]>.
root@u1804:~#
Sou novo no sed e criei abaixo o fluxo de trabalho do sed com base no meu entendimento (corrija-me se encontrar algo errado).
Portanto, parece que a impressão automática padrão do espaço do padrão sempre incluirá uma nova linha no final. Minha pergunta é, p
incluirá uma nova linha também? Tenho exemplos abaixo.
root@u1804:~# seq 3 | sed -rn 'p'
1
2
3
root@u1804:
Aqui a nova linha no final de cada número é adicionada pelo próprio sed (veja o diagrama "adiciona nova linha ao espaço do padrão"). Portanto, parece p
que não anexará uma nova linha. No entanto, veja o exemplo abaixo.
root@u1804:~# seq 3 | sed -rn 'x;p;x;p'
1
2
3
root@u1804:~#
Aqui x
, troque o espaço de padrão com o espaço de espera, o que resultará em um espaço de padrão vazio. Agora p
se aplica ao espaço do padrão (nada nele) deve imprimir nada. Mas com base no resultado, parece que aqui p
imprime uma nova linha. Para mim, parece que este é um comportamento inconsistente. Alguém pode explicar?
Para responder a sua pergunta principal:
O GNU
sed
anexará um<newline>
caractere ao executar op
comando, a menos que a linha de entrada não tenha seu<newline>
caractere final (veja os esclarecimentos sobre as linhas abaixo).Até onde eu sei, o sinalizador de
sed
'sp
e seu recurso de impressão automática implementam a mesma lógica para gerar o espaço de padrão: se o<newline>
caractere final foi removido, eles o adicionam de volta; caso contrário, não.Exemplos:
Em ambos os casos não há
<newline>
caractere (0a
) na saída para as linhas de entrada que não possuem um.Sobre seus diagramas:
"Adiciona nova linha ao espaço de padrão" provavelmente é impreciso porque o
<newline>
caractere não é colocado no espaço de padrão 1 . Além disso, essa etapa não está relacionada à-n
opção - mas isso não torna o diagrama errado ; em vez disso, provavelmente deve ser mesclado em "Espaço de padrão de impressão".Ainda assim, concordo com você sobre a falta de clareza da documentação.
1 A frase que você cita em sua própria resposta , "o conteúdo do espaço de padrão é impresso no fluxo de saída, adicionando de volta a nova linha à direita se for removida", significa que o
<newline>
é anexado ao fluxo, não ao espaço de padrão. Claro, como o espaço do padrão é limpo em pouco tempo, esse é um ponto realmente menorSobre seus testes envolvendo o
x
sinalizador:Internamente, o espaço de padrão e o espaço de espera são estruturas e "meu
<newline>
caractere à direita foi descartado?" é membro deles. Vamos chamá-lo de chomped (como é chamado nosed
código-fonte do ', a propósito).O espaço de padrão é preenchido com uma linha de leitura e seu atributo chomped depende de como essa linha é terminada:
true
se terminar com um<newline>
caractere,false
caso contrário. Por outro lado, hold space é inicializado como vazio e seu chomped atribuído é apenas definido comotrue
.Portanto, quando você troca o espaço de padrão e o espaço de espera e imprime o que nasceu como espera e agora é padrão, um
<newline>
caractere é impresso.Exemplos - esses comandos têm a mesma saída:
(Eu dei apenas uma breve olhada no
sed
código de , então isso pode não ser preciso).Sobre as linhas (esclarecimento iniciado com comentários à sua resposta ):
Escusado será dizer que uma linha sem um caractere final
<newline>
é um conceito problemático. Citando POSIX :Além disso, POSIX define um arquivo de texto:
Finalmente, POSIX em
sed
(mina em negrito):GNU
sed
, no entanto, parece ser menos rigoroso ao definir sua entrada:Assim, em relação à minha primeira frase, devemos levar em conta que, para GNU
sed
, o que é lido no espaço de padrões não precisa necessariamente ser uma linha de texto bem formada.Editei minha resposta para incluir apenas um diagrama atualizado com base na resposta de fra-san. O único propósito é que novos usuários do sed façam referência.
No GNU sed: O comando
p
adicionará uma nova linha à direita apenas se estiver no texto de origem (uma foi removida da entrada quando colocada no espaço do padrão), mas também adicionará uma nova linha à esquerda se o texto adicional for impresso no mesmo fluxo.Uma nova linha à direita pode estar faltando na entrada apenas na última linha.
Imprima apenas a última linha, que terá uma nova linha apenas se o arquivo de origem já tiver uma nova linha nessa última linha:
Da info sed:
Algumas outras versões do sed podem adicionar uma nova linha à direita e/ou emitir um aviso.