¿Cómo usar `jq` en una tubería de shell?

195

Parece que no puedo jqcomportarme "normalmente" en una tubería de shell. Por ejemplo:

$ curl -s https://api.github.com/users/octocat/repos | jq | cat

da como resultado jqsimplemente imprimir su texto de ayuda *. Lo mismo sucede si intento redirigir jqla salida a un archivo:

$ curl -s https://api.github.com/users/octocat/repos | jq > /tmp/stuff.json

¿Está jqrescatando deliberadamente si determina que no se está ejecutando desde un tty? ¿Cómo puedo evitar este comportamiento para poder usarlo jqen una tubería?


* (Me doy cuenta de que este ejemplo contiene un uso inútil del gato ; es solo para fines ilustrativos)

mgalgs
fuente

Respuestas:

323

Debe proporcionar un filtro como argumento. Para pasar el JSON sin modificaciones, aparte de la impresión bonita que jqproporciona de forma predeterminada, use el filtro de identidad .:

curl -s https://api.github.com/users/octocat/repos | jq '.' | cat
chepner
fuente
23
Lo dejé adentro porque el OP lo tenía; Supongo que es solo un marcador de posición para indicar que jqes tanto leer de una tubería como escribir en otra tubería. Si el deseo es simplemente ver la salida de jq, entonces catsí mismo es innecesario.
chepner
3
(1) jq versión 1.5 se ha mejorado para que el. es innecesario en casos como este. (2) No es necesario citar el ".".
pico
66
@peak Puede que no sea necesario para una tubería, pero tengo 1.5 y tuve que proporcionar el "." para redirigir la salida a un archivo.
MHarris
2
Cito .por costumbre, ya que mi práctica estándar es ver primero cómo se ve el JSON, luego regresar y comenzar a agregar al filtro, que la mayoría de las veces será necesario citar.
chepner 05 de
66
@WalterTross Sí, y expliqué en un comentario hace 18 meses por qué lo cito.
chepner
15

Un caso de uso que me he encontrado haciendo frecuentemente también es "¿Cómo construyo datos JSON para suministrarlos a otros comandos de shell, por ejemplo curl?" La forma en que hago esto es usando la --null-input/-nopción:

¡No lea ninguna entrada en absoluto! En cambio, el filtro se ejecuta una vez usando nullcomo entrada. Esto es útil cuando se usa jqcomo una calculadora simple o para construir datos JSON desde cero.

Y un ejemplo pasándolo a curl:

jq -n '{key: "value"}' | curl -d @- \
  --url 'https://some.url.com' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'
mkobit
fuente
9
Eso es genial, pero ¿no estás seguro de cómo es relevante para esta pregunta?
mgalgs
2
@mgalgs Me encontré con ganas de generar / usar jqal comienzo de una tubería de shell en lugar de en el medio / final para filtrar algunos datos. El curlejemplo es básico, pero a menudo me encuentro escribiendo a mano los datos de JSON curly tratando de citar correctamente, así que pensé que podría ser útil también para otros.
mkobit