AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 493141
Accepted
Just a learner
Just a learner
Asked: 2019-01-08 20:00:35 +0800 CST2019-01-08 20:00:35 +0800 CST 2019-01-08 20:00:35 +0800 CST

Gnu sed, o comando p anexará uma nova linha ao imprimir?

  • 772
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).

insira a descrição da imagem aqui

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 é, pincluirá 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 pque 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 pse aplica ao espaço do padrão (nada nele) deve imprimir nada. Mas com base no resultado, parece que aqui pimprime uma nova linha. Para mim, parece que este é um comportamento inconsistente. Alguém pode explicar?

sed
  • 3 3 respostas
  • 1886 Views

3 respostas

  • Voted
  1. Best Answer
    fra-san
    2019-01-10T06:53:03+08:002019-01-10T06:53:03+08:00

    Para responder a sua pergunta principal:

    O GNU sedanexará um <newline>caractere ao executar o pcomando, 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's pe 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:

    $ printf '%s\n%s' '4' '5' | sed ';' | hexdump -C      # auto-print
    00000000  34 0a 35                                          |4.5|
    00000003
    
    $ printf '%s\n%s' '4' '5' | sed -n 'p;' | hexdump -C  # no auto-print; p flag
    00000000  34 0a 35                                          |4.5|
    00000003
    

    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 à -nopçã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 menor


    Sobre seus testes envolvendo o xsinalizador:

    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 no sedcó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: truese terminar com um <newline>caractere, falsecaso contrário. Por outro lado, hold space é inicializado como vazio e seu chomped atribuído é apenas definido como true.
    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:

    $ printf '\n' | sed -n 'p;' | hexdump -C        # input is only a <newline>
    00000000  0a                                                |.|
    00000001
    
    $ printf '%s' '5' | sed -n 'x;p;' | hexdump -C  # input has no <newline>
    00000000  0a                                                |.|
    00000001
    

    (Eu dei apenas uma breve olhada no sedcó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 :

    3.206 Linha
    Uma sequência de zero ou mais não <newline>caracteres mais um caractere final <newline>.

    Além disso, POSIX define um arquivo de texto:

    3.403 Arquivo de Texto
    Um arquivo que contém caracteres organizados em zero ou mais linhas. ...

    Finalmente, POSIX em sed(mina em negrito):

    DESCRIÇÃO
    O sedutilitário é um editor de fluxo que deve ler um ou mais arquivos de texto , fazer alterações de edição de acordo com um script de comandos de edição e gravar os resultados na saída padrão. ...

    GNUsed , no entanto, parece ser menos rigoroso ao definir sua entrada:

    sedé um editor de fluxo. Um editor de fluxo é usado para realizar transformações básicas de texto em um fluxo de entrada (um arquivo ou entrada de um pipeline). ...

    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.

    • 5
  2. Just a learner
    2019-01-09T08:34:47+08:002019-01-09T08:34:47+08:00

    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.

    insira a descrição da imagem aqui

    • 4
  3. user232326
    2019-01-12T01:57:15+08:002019-01-12T01:57:15+08:00

    No GNU sed: O comando padicionará 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.

     $ printf 'abc' | od -An -c
        a   b   c                                 # no newline.
    
     $ printf 'abc' | sed '' | od -An -c
        a   b   c                                 # also no newline.
    
     $ printf 'abc' | sed -n 'p' | od -An -c
        a   b   c                                 # still no newline.
    
     $ printf 'abc' | sed -n 'p;p' | od -An -c
        a   b   c  \n   a   b   c                 # leading newline added.
    

    Imprima apenas a última linha, que terá uma nova linha apenas se o arquivo de origem já tiver uma nova linha nessa última linha:

     $ printf 'abc\ndef' | sed -n '$p' | od -An -c
        d   e   f
    

    Da info sed:

    ---------- Notas de rodapé ----------

    (1) Na verdade, se 'sed' imprimir uma linha sem a nova linha final, ele imprimirá a nova linha ausente assim que mais texto for enviado para o mesmo fluxo de saída, o que dá a "surpresa menos esperada" mesmo que não faça comandos como 'sed -n p' exatamente idênticos a 'cat'.

    Algumas outras versões do sed podem adicionar uma nova linha à direita e/ou emitir um aviso.

    • 1

relate perguntas

  • Linux grep o que no arquivo 1 está no arquivo 2 [duplicado]

  • como grep linhas após a terceira vírgula com condição

  • remova o número de linhas duplicadas com base na correspondência antes da primeira vírgula

  • Como posso melhorar este script de conversão de personagens?

  • Como remover uma única linha entre duas linhas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve