br apenas removendo \ n fornecido pelo comando sed '='

7

Eu criei um arquivo usando:

printf 'this is \n not is \n is is \n this biz' > file2

quando eu tento remover tudo \ n (nova linha), ele apenas remove a nova linha do número inserido do sed

sed  '=' file2 | sed 'N; s/\n/ /' 

a saída é:

 1 this is 
 2  not is 
 3  is is 
 4  this biz

e não o que eu esperava:

1 this is  2  not is  3  is is  4  this biz

Estou perdido.

    
por Linux Newbie 15.06.2018 / 20:12

5 respostas

7

Seu segundo script sed ,

N
s/\n/ /

não funciona da maneira esperada, pois lerá uma linha e, em seguida, anexará a próxima linha a ela com uma nova linha inserida pelo comando N e, em seguida, substituirá essa nova linha por um espaço (e saída). Ao ler a linha depois, esse resultado das duas primeiras linhas é descartado.

Em vez disso, você teria que usar o espaço de espera:

H;            # append to hold space with a '\n' embedded
              # for the last line:
${
    x;        # swap in the hold space
    s/\n//;   # delete the first newline (from the H command on the very first line of input)
    y/\n/ /;  # replace all other newlines with spaces
    p;        # print result
}

Esse script está sendo executado uma vez para cada linha de entrada, coletando dados no espaço de espera até chegarmos à última linha. Na última linha, processamos os dados coletados e os geramos.

Você executaria isso com sed -n :

$ sed '=' <file2 | sed -n 'H; ${ x; s/\n//; y/\n/ /; p; }'
1 this is  2  not is  3  is is  4  this biz

(não há nova linha no final da saída, pois não havia nenhuma no final da entrada).

Como alternativa, com um loop explícito, podemos usar N . O truque aqui é nunca chegar ao final do script até que estejamos prontos para imprimir o resultado.

:top;     # define label 'top'
N;        # append next line with a '\n' embedded
$!btop;   # if not at end, branch to 'top'
y/\n/ /;  # replace all newlines with spaces
          # (implicit print)

Este script só é executado (até o final) uma vez e gerencia a leitura dos dados enquanto o script anterior foi alimentado com dados pelo loop de leitura interno em sed (que substitui o espaço padrão para cada linha lida, qual foi o seu problema). Ele usa o espaço de padrão, em vez do espaço de armazenamento, para coletar os dados e processá-los quando a última linha foi lida.

Na linha de comando:

$ sed '=' <file2 | sed ':top; N; $!btop; y/\n/ /'

(mesma saída acima)

    
por 15.06.2018 / 20:37
4

Se o GNU sed , tente isto

$ sed -z 's/\n/ /g' file2
this is   not is   is is   this biz
$

tr faz um trabalho igualmente bom.

$ tr '\n' ' ' <file2
this is   not is   is is   this biz
$
    
por 15.06.2018 / 20:20
3

Isso é fundamental porque sed é orientado a linha. O que acontece é

  • sed carrega a primeira linha 1 no espaço padrão
  • o comando N carrega a próxima linha e a anexa ao espaço padrão, separado por \n , dando 1\nthis is
  • substituímos \n pelo espaço dando 1 this is

e terminamos; o espaço do padrão é impresso e, em seguida, os passos são repetidos para cada um dos restantes (pares de) linhas.

    
por 15.06.2018 / 20:32
0

O comando que você usou apenas processar linhas em pares .
A primeira linha é o número da linha (impresso pelo comando = ).
A segunda linha é anexada à primeira, uma nova linha é removida e impressa.
Então, o próximo par de linhas é igualmente processado.

A única maneira de processar linhas all é acumulá-las até a última linha.
Nesse momento, todas as novas linhas podem ser apagadas / traduzidas para espaços:

$ sed '=' file | sed ':start;N;$bend;bstart;:end;y/\n/ /'
1 this is  2  not is  3  is is  4  this biz

Uma linha mais curta (mas também mais lenta, o que não é um problema com este arquivo muito curto) é:

sed ':1;N;s/\n/ /;t1'

Observe que as duas soluções acima armazenarão o arquivo inteiro na memória.

Mas, é claro, tr é uma ferramenta melhor para esse trabalho:

$ sed '=' file | tr '\n' ' '

Ou, também, paste (que mantém a nova linha à direita):

$ sed '=' file | paste -sd ' '
1 this is  2  not is  3  is is  4  this biz
    
por 15.06.2018 / 23:07
0

Tentei com o comando abaixo e funcionou bem

inputfile

this is
 not is
 is is

comando:

cat inputfile|sed "="| sed "N;s/\n/ /g"| sed "N;s/\n/ /g"| sed "N;s/\n/ /g"

saída

1 this is  2  not is  3  is is  4  this biz
    
por 16.06.2018 / 07:17