Retorno de carro, comportamento de LineFeed e Sed

1

Eu preciso entender por que o sed pode funcionar para 1) e não para 2). Por favor, não me envie nenhuma solução alternativa. Eu já os encontrei neste fórum. Eu só preciso entender o comportamento do sed em relação ao ponto 1) e 2).

1) sed -i s/\r//g file.txt

Ao verificar od -c file.txt, o sed removeu com sucesso \ r

2) sed -i s/\n//g file.txt

Ao verificar od -c file.txt, o sed não foi removido \ n

Minha pergunta aqui é apenas entender por que não está funcionando para o ponto-2. Por favor, não poste nenhuma solução alternativa. Deseja entender os componentes internos!

    
por LoveWithMaths 07.04.2018 / 14:07

2 respostas

7

De GNU sed manual - Como funciona o sed

sed operates by performing the following cycle on each line of input: first, sed reads one line from the input stream, removes any trailing newline, and places it in the pattern space. Then commands are executed; each command can have an address associated to it: addresses are a kind of condition code, and a command is only executed if the condition is verified before the command is to be executed.

When the end of the script is reached, unless the -n option is in use, the contents of pattern space are printed out to the output stream, adding back the trailing newline if it was removed. Then the next cycle starts for the next input line.

De especificação POSIX (obrigado steeldriver para o link)

In default operation, sed cyclically shall append a line of input, less its terminating newline, into the pattern space. Normally the pattern space will be empty, unless a D command terminated the last cycle. The sed utility shall then apply in sequence all commands whose addresses select that pattern space, and at the end of the script copy the pattern space to standard output (except when -n is specified) and delete the pattern space. Whenever the pattern space is written to standard output or a named file, sed shall immediately follow it with a newline.


tl; dr o separador de registro de entrada (que é novo por padrão) é removido antes de executar os comandos e, em seguida, adicionado de volta durante a impressão do registro


Existem, no entanto, casos em que o caractere de nova linha pode ser manipulado. Alguns exemplos dados abaixo:

$ # this would still not allow newline of second line to be manipulated
$ seq 5 | sed 'N; s/\n/ : /'
1 : 2
3 : 4
5

$ # here ASCII NUL is input record separator, so newline can be freely changed
$ seq 5 | sed -z 's/\n/ : /g'
1 : 2 : 3 : 4 : 5 :  

$ # default newline separator, so NUL character can be changed
$ printf 'foo
$ # this would still not allow newline of second line to be manipulated
$ seq 5 | sed 'N; s/\n/ : /'
1 : 2
3 : 4
5

$ # here ASCII NUL is input record separator, so newline can be freely changed
$ seq 5 | sed -z 's/\n/ : /g'
1 : 2 : 3 : 4 : 5 :  

$ # default newline separator, so NUL character can be changed
$ printf 'foo%pre%baz%pre%xyz%pre%' | sed 's/\x0/-/g'
foo-baz-xyz-
$ # NUL character is separator, so it cannot be changed now
$ printf 'foo%pre%baz%pre%xyz%pre%' | sed -z 's/\x0/-/g' | cat -A
foo^@baz^@xyz^@
baz%pre%xyz%pre%' | sed 's/\x0/-/g' foo-baz-xyz- $ # NUL character is separator, so it cannot be changed now $ printf 'foo%pre%baz%pre%xyz%pre%' | sed -z 's/\x0/-/g' | cat -A foo^@baz^@xyz^@
    
por 07.04.2018 / 15:34
2

Um arquivo para sed é um fluxo de linhas delimitadas por \n . Se \n é o delimitador, é claro que não pode manipulá-lo em substituições.

    
por 07.04.2018 / 14:30