How to Extract Text from Claude Code JSON Stream Output

2026-01-09 10:55 (18 hours ago) ytyng

Background / Problem

When you use Claude Code’s --output-format=stream-json option, you get streaming output in JSON Lines format like this:

{"type":"stream_event","event":{"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"容を"}},...}
{"type":"stream_event","event":{"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"レビューして"}},...}
{"type":"stream_event","event":{"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"問"}},...}

From this stream, you want to extract only the text content in the .event.delta.text field and display it in real time in the terminal.

Requirements

Attempt 1: The problem with jq -r

The first method tried:

claude code ... | jq -r '.event.delta.text? // empty'

Issues: - The -r (--raw-output) option appends a newline after each output result - Fragments like “容を”, “レビューして”, “問” end up each on their own line - As a result, text that should be continuous gets broken up unnaturally

Solution: The jq -j option

Final solution:

claude code の ${HOME}/.claude/local/claude \
  --verbose --permission-mode delegate \
  --print --output-format=stream-json --include-partial-messages "/push-with-review" \
  | jq -j '.event.delta.text? // empty'

Characteristics of jq -j (--join-output)

When you need to handle multiple message types

| jq -j '
  (.event.delta.text? // empty),
  (.message.content[]?.text? // empty)
'

This lets you continuously output text from both stream_event and assistant messages.

jq filter details

jq features used

  1. Optional operator (?)
  2. Using .event.delta.text? prevents errors even if the field doesn’t exist

  3. Alternative operator (//)

  4. // empty outputs nothing when the value is null or undefined

  5. Strict filtering with select() (alternative) bash | jq -j 'select(.event.delta.text != null) | .event.delta.text'

Reference

jq option comparison

Option Behavior Use case
-r (--raw-output) Adds a newline after each result When you want to process line by line
-j (--join-output) Does not add newlines When you want continuous text output
-c (--compact-output) Compresses JSON into one line Keep JSON structure while compacting

Reference URLs

Conclusion

To extract only the text from Claude Code’s streaming output, jq’s -j option is the best fit.

Practical examples

# Basic form
claude -p "タスク内容" | jq -j '.event.delta.text? // empty'

# Filter only stream_event
claude -p "タスク内容" | jq -j 'select(.type == "stream_event") | .event.delta.text? // empty'

With this, you can display Claude Code output in a human-readable format in real time.

Currently unrated
The author runs the application development company Cyberneura.
We look forward to discussing your development needs.

Archive

2026
2025
2024
2023
2022
2021
2020
2019
2018
2017
2016
2015
2014
2013
2012
2011