O que você está vendo aqui é o buffer de armazenamento em ação. Ele armazenará a saída em um buffer até atingir um determinado limite (pode ser de 512 bytes ou 4KB ou maior) e, em seguida, enviar tudo de uma vez.
Este buffer é desativado automaticamente se o stdout estiver conectado a um terminal, mas quando estiver conectado a um pipe (como no seu caso), ele ativará esse comportamento de armazenamento em buffer.
A maneira usual de desabilitar / controlar o buffer é usar a função setvbuf()
(veja esta resposta para mais detalhes), mas isso precisaria ser feito no código fonte de jq
, então talvez não seja algo prático para você ...
Há uma solução alternativa ... (Um hack, pode-se dizer.) Existe um programa chamado "unbuffer", que é distribuído com "expect" que pode criar um pseudo-terminal e conectá-lo a um programa. Portanto, mesmo que jq
ainda esteja escrevendo para um pipe, ele pensará que está escrevendo em um terminal e o efeito de buffer será desativado.
Instale o pacote "expect", que deve vir com "unbuffer", se você ainda não o tiver ... Por exemplo, no Debian (ou Ubuntu):
$ sudo apt-get install expect
Então você pode usar este comando:
$ tail -f in.txt | unbuffer -p jq '.f1' | tee out.txt
Veja também esta resposta para mais detalhes sobre "unbuffer", e você pode encontrar uma página man aqui também .