bash / sed / awk / etc remove todas as outras novas linhas

37

um comando bash gera isto:

Runtime Name: vmhba2:C0:T3:L14
Group State: active
Runtime Name: vmhba3:C0:T0:L14
Group State: active unoptimized
Runtime Name: vmhba2:C0:T1:L14
Group State: active unoptimized
Runtime Name: vmhba3:C0:T3:L14
Group State: active
Runtime Name: vmhba2:C0:T2:L14
Group State: active

Eu gostaria de passar isso para algo que pareça com isso:

Runtime Name: vmhba2:C0:T1:L14 Group State: active 
Runtime Name: vmhba3:C0:T3:L14 Group State: active unoptimized
Runtime Name: vmhba2:C0:T2:L14 Group State: active
[...]

i.e. remova todas as outras novas linhas

Eu tentei ... |tr "\nGroup" " " , mas ele removeu todas as novas linhas e também escreveu algumas outras letras. obrigado

    
por carillonator 29.03.2012 / 23:53

8 respostas

67

não pode testar agora, mas

... | paste - - 

deve fazer isso

    
por 30.03.2012 / 01:00
10

Uma possibilidade é:

awk 'ORS=NR%2?" ":"\n"'

Se o número da linha for divisível por 2, termine com uma nova linha, caso contrário, termine com um espaço.

(Testado em: CentOS 6, GNU Awk 3.1.7)

Usando sed (consulte explicação ):

sed ':a;N;$!ba;s/\nGroup/ Group/g'

Leitura adicional:

por 30.03.2012 / 00:17
8

Se você quiser usar sed , não há razão para ler todo o arquivo na memória. Você pode mesclar todas as outras linhas assim:

sed 'N;s/\n/ /' inputfile

Use qualquer personagem que você queira em vez do espaço.

Aqui está outra maneira de usar o awk:

awk '{printf "%s", $0; if (getline) print " " $0; else printf "\n"}' inputfile

O if/else manipula o caso em que há um número ímpar de linhas no arquivo. Sem ela, a última linha estranha é impressa duas vezes. Caso contrário, para comparação, você poderia fazer:

awk '{printf "%s", $0; getline; print " " $0}'
    
por 30.03.2012 / 06:20
3

A maneira mais idiomática de fazer isso em awk é a seguinte:

awk 'ORS=NR%2?FS:RS' file

Produz:

Runtime Name: vmhba2:C0:T3:L14 Group State: active
Runtime Name: vmhba3:C0:T0:L14 Group State: active unoptimized
Runtime Name: vmhba2:C0:T1:L14 Group State: active unoptimized
Runtime Name: vmhba3:C0:T3:L14 Group State: active
Runtime Name: vmhba2:C0:T2:L14 Group State: active

Para explicar, precisamos definir cada uma das variáveis incorporadas:

  • RS record separador. Padrões para \n (nova linha).
  • ORS separador de registro de saída. Padrões para \n (nova linha).
  • FS separador de campos. Padrões para (espaço).
  • NR número de registros.

Como o separador de registro padrão é a nova linha, um registro é, por padrão, uma linha.

NR%2 é o módulo de NR/2 , de modo que seja 0 ou 1 . 0 para linhas pares e 1 para linhas ímpares.

var=condition?condition_if_true:condition_if_false é o operador ternário.

Todos juntos, dizendo ORS=NR%2?FS:RS , estamos definindo o separador de registros de saída:

  • se o número de registros estiver no formato 2k + 1 , ou seja, em linhas pares, os separadores de registro de saída serão definidos como FS , ou seja, um espaço.
  • se o número de registros estiver no formato 2k , ou seja, em linhas ímpares, os separadores de registros de saída serão definidos como RS , ou seja, uma nova linha.

Dessa forma, as linhas ímpares terminam com um espaço, que é então unido à próxima linha. Depois dessa linha, uma nova linha é impressa.

Mais informações em awig idiomático .

    
por 08.10.2014 / 09:31
2

Isso funciona para mim no Linux:

... | tr "\n" " "

Isso substitui um espaço vazio por um caractere de nova linha; você deve escapar do caractere de nova linha para que as coisas funcionem corretamente.

    
por 30.03.2012 / 14:49
2

No bash:

... | while read l1; do read l2; echo "$l1 $l2"; done
    
por 05.04.2012 / 12:14
1

Se o Perl é uma opção:

perl -pe 's/\n/ / if $. % 2 == 1' file

s/\n/ / substitui a nova linha pelo espaço
$. é o número da linha

    
por 10.11.2015 / 20:31
-1

Que tal usar grep ?

.. | grep -v '^Group State'
    
por 30.03.2012 / 06:28