Acabei de ver um exemplo de uso echo
para colocar várias coisas no pipeline (para jq
).
echo '{"A": {"a": 1}}' '{"A": {"b": 2}}' '{"B": 3}' |\
jq --slurp 'reduce .[] as $item ({}; . * $item)'
Se bem entendi, isso parece colocar três objetos no pipeline de um lado e, do outro, jq
recebê-los e colocá-los em um array e reduzi-lo com um operador de mesclagem.
Isso é surpreendente para mim e não tenho certeza de como funciona ter várias coisas no arquivo stdin
.
Mais especificamente, como o sistema sabe que a entrada é de três arquivos e onde cada arquivo começa/termina?
Se eu apenas fizer a parte echo echo '{"A":1}' '{"A": {"b": 2}}' '{"B": 3}'
, a saída não parece ter nenhum delimitador visível entre os três objetos:
{"A":1} {"A": {"b": 2}} {"B": 3}
As aspas simples têm alguns efeitos especiais que informam ao próximo filtro ( jq
) os limites? Ou como jq conhece os limites?
(Isso é com Ubuntu 24.04, jq 1.7.1)
Não faz nada disso. Não há objetos; há apenas um "fluxo" de personagens.
echo
imprime todos os argumentos obtidos, separados por espaços. Se você fizerecho 'a' 'b' 'c'
isso, a saída seráa b c
; um único fluxoDa mesma forma, sua instrução echo apenas produz a saída
{"A": {"a": 1}} {"A": {"b": 2}} {"B": 3}
. Novamente, apenas um único fluxo de caracteres.O
jq
comando sabe o suficiente sobre JSON para saber que esses caracteres significam algo (um conjunto de objetos JSON separados), mas paraecho
o pipeline é apenas um fluxo de caracteres sem sentido.Você obteria exatamente o mesmo resultado se o fizesse
echo '{"A": {"a": 1}} {"A": {"b": 2}} {"B": 3}'
. Ou mesmo algo comoecho '{"A":' '{"a":' "1}}" '{"A": {"b": 2}} {"B": 3}'
Observe também que você pode produzir saída de vários comandos para o pipeline, e o resultado ainda é apenas a concatenação de todos os bytes envolvidos. Por exemplo, aqui,
foobar
é unido em uma única linha: