Como eu posso dobrar as novas linhas em um fluxo de saída [duplicado]

11

Quando tenho um fluxo de saída:

a
b
c
d
e

Como posso dobrar as novas linhas:

a

b

c

d

e

    
por Anthon 03.11.2014 / 21:43

6 respostas

20
sed G

é um conhecido conhecido <-line> para isso.

Em termos de desempenho, o mais eficaz com o baú de ferramentas padrão do Unix provavelmente seria:

paste -d '\n' - /dev/null

Se você não quiser adicionar uma linha vazia após a última linha:

sed '$!G'

Para adicionar as linhas vazias antes das linhas de entrada:

paste -d '\n' /dev/null -

Ou:

sed 'i\
/'
    
por 03.11.2014 / 22:03
5

usando pr : paginando arquivos

pr -t -d file.txt

saída:

a

b

c

d

e

usando awk :

awk '{printf("%s\n\n",$0)}' file.txt
    
por 03.11.2014 / 22:21
4

Com awk você pode definir o Output Record Separator como nova linha dupla:

awk -v ORS="\n\n" 1 file

Em seguida, 1 executa a ação awk padrão: {print $0} , ou seja, imprime a linha atual.

    
por 04.11.2014 / 11:08
4

Embora sed seja a escolha óbvia, outro candidato muito confiável pode ser dd .

Provavelmente é mais útil para situações em que a contagem de bytes é mais importante do que a contagem de linhas, mas block ing e desbloqueio dados é o que faz melhor:

seq 10| dd cbs=16 conv=block                             
1               2               3               4               5               6               7               8               9               10              

Isso, até agora, é mais como alcançar o oposto do que você pediu, mas dd pode bloquear linhas em espaços - ele converterá entrada \n ewlines em espaços e pad essas linhas em cbs=[num] bytes de espaços. E assim, se você puder prever com segurança um comprimento máximo de bytes por linha (porque adivinhar muito baixo resultará em truncamento) , e então dobrar esse número ...

seq 10| dd cbs=16 conv=block | dd cbs=8 conv=unblock

1

2

3

4

5

6

7

8

9

10

... você pode então desbloquear a metade do cbs - que irá aparar espaços à direita e imprimir \n ewline a cada cbs=[num] bytes. Isso é muito mais útil para lidar com grandes volumes de dados possivelmente binários (ou para entrada de terminal) do que seria para arquivos de texto comuns, mas é uma alternativa - e pode competir definitivamente (em larga escala) no departamento de performance com praticamente qualquer coisa.

Outra alternativa especializada pode ser nl e tr . Isso só seria útil se sua entrada se assemelha à mostrada - porque a solução envolve tr anslating espaços em \n ewlines. Em qualquer caso, nl sempre insere pelo menos -w idth + 1 bytes de espaços na cabeça de cada linha pela qual é passado - independentemente de os numerar ou não. E assim você pode ...

printf %s\n a b c d e |
nl -bn |
tr -s \  \n

... que imprime:


a

b

c

d

e

A opção -bn instrui nl não a numerar o corpo de sua entrada, mas ainda insere 6 espaços por padrão - e pelo menos dois pares com um argumento -w1 . Isso pode torná-lo útil para outros casos também - como ...

INPUT |nl -bn -w1 |sed '/address/s/  //...' | sed '/^  /!...'

... em que o segundo sed sempre sabe quais linhas o primeiro tocou. Mas eu discordo ...

De qualquer forma, tr -s queezes todas as sequências de entrada de espaços em um único byte e tr anslates cada resultado em um \n ewline. Sem a opção -s , haveria seis novas ewlines \n intervenientes entre cada alfabético acima. E isso pode ser definido com segurança tão facilmente quanto -w1 .

Ainda assim, eu usaria sed . E por falar nisso, embora os comandos G et e i nsert já tenham sido mencionados, há também os comandos a ppend e c hange para isso. Qualquer um dos dois ficaria assim:

printf %s\n a b c d e|
sed 'a\
'
a

b

c

d

e

sed G funciona porque G ets o conteúdo do buffer H old anexado ao buffer de padrão após um \n ewline. H old space é, por padrão, vazio e, portanto, tudo que você obtém é um \n ewline. Mas, se houver mais no script sed e o buffer H old não estiver vazio , você poderá sempre a ppen em qualquer cadeia em qualquer linha, senão você pode p rint a linha então c altere na saída como:

INPUT| sed '...;p;c\
'

... com GNU sed a nova linha atual não é necessária para i , c ou a e todos os três podem ser usados como sed '[aic]\' , embora talvez isso seja um mau hábito a ser adotado. Em qualquer caso, qualquer um desses três é provavelmente menos dispendioso do que um s/// ubstitution porque nenhum implica um padrão de regex, embora eu duvide que a diferença seja significativa.

    
por 04.11.2014 / 14:13
3

Você pode percorrer sed :

.... | sed 's/$/\n/'
    
por 03.11.2014 / 21:43
3

Usando o perl, você pode adicionar uma nova linha antes

...|perl -pe 's/^/\n/'

ou depois de cada linha:

...|perl -pe 's/$/\n/'
    
por 03.11.2014 / 22:22