Um programa que pode armazenar em buffer stdin ou arquivo

11

Além de usar um arquivo temporário para ajudar, existe um caminho / programa que pode armazenar em buffer a entrada de stdin , mas não produz o conteúdo até obter o EOF . Eu não quero usar uma variável shell (por exemplo, buffer=$(cat) ).

Este programa deve se comportar como abaixo (suponha que o nome do programa seja buffered-cat ):

$ buffered-cat
line 1
line 2
line 3
^D # Ctr-D here(End of Line)

Agora que o programa recebeu ^D , o buffered-cat gera o conteúdo

line 1
line 2
line 3
    
por Ekeyme Mo 13.01.2017 / 07:12

6 respostas

16

Um homem pobre sponge usando awk :

awk '{a[NR] = $0} END {for (i = 1; i <= NR; i++) print a[i]}'

Se você tiver tac , você também pode usá-lo incorretamente:

... | tac | tac
    
por 13.01.2017 / 07:48
28

Você pode fazer isso com sponge de moreutils . sponge "absorverá a entrada padrão e gravará em um arquivo". Sem argumentos, esse arquivo é a saída padrão. A entrada dada a este comando é armazenada na memória até EOF e, em seguida, escrita de uma só vez.

Para gravar em um arquivo normal, você pode apenas fornecer o nome do arquivo:

cmd | sponge filename

O objetivo principal de sponge é permitir a leitura e a gravação do mesmo arquivo em um pipeline, mas também faz o que você deseja.

    
por 13.01.2017 / 07:20
6

Contanto que sua entrada seja texto ASCII (não contenha nenhum byte NUL 0x0 até o final), então sed -z faz o que você deseja:

$ sed -z ''
Line 1
Line 2
Line 3
^D
Line 1
Line 2
Line 3
$ 

O -z faz com que sed trate o byte NUL como um delimitador de linha em vez da nova linha usual. Portanto, contanto que sua entrada seja um texto regular sem bytes NUL, o sed continuará lendo toda a entrada em seu buffer padrão até que o EOF seja atingido. sed então não faz nenhum processamento no buffer e o exibe.

Se houver bytes NUL em sua entrada, você poderá fazer isso:

sed ':l;N;bl'
    
por 13.01.2017 / 18:28
4

Esta solução sed é um pouco maior que a do DigitalTrauma, mas também trabalha com bytes NUL.

sed -n 'H;${x;s/^\n//;p}'
    
por 13.01.2017 / 21:01
1

O comportamento que você está pedindo, não é o comportamento padrão do gato simples?

gv@debian:$ cat << EOF #or cat <<EOF >file or cat <<EOF >/dev/stdout
> Line 1
> Line 2
> Line 3
> EOF
Line 1
Line 2
Line 3
gv@debian:$
    
por 14.01.2017 / 02:03
1

Mesma idéia que o exemplo do awu do muru, exceto em Python. Use Ctrl D para parar de ler em linhas

$ python -c 'import sys;print("".join(sys.stdin.readlines()))'                                                           
line1
line2
line3 # press Enter and Ctrl+D at this point
line1
line2
line3
    
por 14.01.2017 / 06:48