Como posso substituir uma nova linha por sed? [duplicado]

6

Eu tenho texto com espaço em branco (incluindo uma nova linha) que preciso substituir. Gostaria de usar sed , mas o AIX não parece suportar o responde a sed newline questions que encontrei. A versão do bash que estou usando é "GNU bash, versão 3.00.16 (1) -release (powerpc-ibm-aix5.1)"

Se eu executar um comando que produza vários pares de linhas de texto como:

alias:  aliasname
                10:00:00:00:00:00:00:00

Qual é a melhor maneira de criar uma linha para cada uma? Se eu usar ssh user@system command | tr '\n' ' ' , ele substitui as duas novas linhas e eu preciso manter a última, ou então a saída vai para uma única linha.

Edit: o que eu tentei até agora é:

  • | sed -e ':1' -e 'N' -e '$!b1' -e 's/\n/ /g' que substitui todas as novas linhas, colocando todo o fluxo de saída em uma única linha.
  • | while read i; do printf "%s " $i; done; echo , que também substitui todas as novas linhas
  • | tr -d '\n' e | tr -d '\n'; echo , que ainda substituem todas as novas linhas, no entanto, o eco adiciona um de volta ao último comando.
por Basil 30.10.2014 / 16:19

4 respostas

4

Aqui está uma abordagem pura que excluirá a primeira nova linha de cada par:

command | 
  while IFS=$'\n' read i; do 
    let c++; [ "$(expr $c % 2)" -eq "0" ] && echo "$i" || printf "%s " "$i"; 
  done

Se você não precisa manter o espaço em branco inalterado, pode deixar de fora o IFS :

command | 
  while read i; do 
    let c++; [ "$(expr $c % 2)" -eq "0" ] && echo "$i" || printf "%s " "$i"; 
  done

A mesma ideia usando perl :

command | perl -ne 'chomp;$. % 2 == 0 ? print "$_\n" : print "$_"' 
    
por 31.10.2014 / 17:50
5

Mais fácil

ssh user@system command | tr '\n' ' ';echo

Ou se você quiser sed

ssh user@system command | sed 'N;s/\n\s\+/ /'
    
por 30.10.2014 / 16:33
4

Tente isto:

sed -e ':1' -e 'N' -e '$!b1' -e 's/\n/ /g'
    
por 30.10.2014 / 17:20
0

Provavelmente, é melhor fazer isso com sed ; veja Por que usar um loop de shell para processar texto é considerado uma prática ruim? Por exemplo, essa pequena variação da segunda resposta ( sed ) de Costas :

sed 'N; s/\n/ /'

faz um bom trabalho ao responder a pergunta: N para acrescentar a próxima linha de entrada no espaço padrão e, em seguida, s/\n/ / para fazer a substituição. (E então esses comandos se repetem para cada duas linhas de entrada).

Mas, se você quiser fazer isso inteiramente no shell, esta variação da resposta de terdon :

while IFS= read -r line1
do
    IFS= read -r line2; printf '%s %s\n' "$line1" "$line2"
done

funciona sem executar nenhum programa externo. A lógica é simples (IMHO): enquanto não no final da entrada, leia uma linha e leia outra linha, e, em seguida, imprima as duas strings, separadas por espaços, em uma linha.

O código acima tem um problema com um caso de borda: se a entrada for um número par de linhas bem formadas seguido por alguns caracteres não terminados com uma nova linha, descarta a linha final (parcial). ( a resposta de terdon tem o mesmo problema, mas não apenas para números pares de linhas. Isso ocorre porque read retorna falha quando lê uma linha parcial, mesmo que ele coloque os dados na variável. Então a correção é esta:

while IFS= read -r line1  ||  [ "$line1" != "" ]
do
    IFS= read -r line2; printf '%s %s\n' "$line1" "$line2"
done

que continua até que read falhe e definem a variável como uma string vazia.

    
por 10.03.2018 / 04:50

Tags