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


39

Um comando bash gera isso:

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 canalizá-lo para algo para torná-lo assim:

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
[...]

ou seja, remova qualquer outra linha nova

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


2
tré inteiramente baseado em caracteres: você pediu a tr para remover novas linhas e todos os 'G', 'r', 'o', 'u' e 'p'.
precisa

Respostas:


80

não pode testar agora, mas

... | paste - - 

deveria fazê-lo


5
+1 - funciona e é elegante. (Ele coloca um separador entre as linhas - paste -d ' ' - -irá adicionar um espaço em vez se necessário)
cyberx86

4
Você poderia explicar como o comando funciona? Por que existem dois -? Graças
bbaja42

7
pasteé utilizado para concatenar as linhas correspondentes de ficheiros: paste file1 file2 file3 .... Se um dos argumentos "arquivo" for "-", as linhas serão lidas a partir da entrada padrão. Se houver 2 argumentos "-", colar terá 2 linhas de stdin. E assim por diante. Veja a página do manual .
Glenn Jackman

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 (veja explicação ):

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

Leitura adicional:


8

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

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

Use qualquer caractere que desejar 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

Ele if/elselida com o caso em que há um número ímpar de linhas no arquivo. Sem ele, a última linha ímpar é impressa duas vezes. Caso contrário, para comparação, você pode fazer:

awk '{printf "%s", $0; getline; print " " $0}'

1
Um comentário tardio: 1) sempre use um especificador de formato para printf, caso a string tenha sinais de porcentagem, 2) para evitar a última linha duplicada, defina $ 0 como "" -awk '{printf "%s", $0; $0=""; getline; print " " $0}'
glenn jackman 10/12/12

3

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

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

Emite:

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 explicá-lo, precisamos definir cada uma das variáveis ​​internas:

  • RSseparador de registros. O padrão é \n(nova linha).
  • ORSseparador de registros de saída. O padrão é \n(nova linha).
  • FSseparador de campo. O padrão é (espaço).
  • NR número de registro.

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

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

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

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

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

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

Mais informações no Idiomatic awk .


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.


Isso remove todas as novas linhas, não todas as outras linhas.
Trenton

2

Na festança:

... | while read l1; do read l2; echo "$l1 $l2"; done

1

Se Perl é uma opção:

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

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


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.