You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用jq合并包含对象与数组的两个JSON文件?

Solution to Merge Harry Potter JSON Files with jq

I get it, your main pain point is that basic jq merge commands are replacing the entire movies array instead of merging individual objects by their title key. Let's fix that with a tailored jq script that meets all your requirements.

Working Command

Here's the jq command that will give you the exact merged result you need (note: this requires jq 1.6 or newer, since it uses the INDEX function):

jq -n '
  # Read file1 and convert its movies array to a dictionary keyed by title
  (input | .movies |= INDEX(.title)) as $file1
  # Read file2 and do the same for its movies array
  | (input | .movies |= INDEX(.title)) as $file2
  # Merge top-level fields (file2 takes priority over file1)
  | $file1 * $file2
  # Reconstruct the movies array by merging objects with matching titles
  | .movies = [
      # Get all unique titles from both dictionaries
      ($file1.movies + $file2.movies | keys_unsorted[] | 
       # Merge each pair of movie objects (file2 fields override file1 if conflict)
       $file1.movies[.] * $file2.movies[.])
    ]
' file1.json file2.json

Let's Break Down What This Does

  1. Convert Arrays to Dictionaries: Using INDEX(.title) turns each movies array into an object where keys are movie titles, and values are the movie objects. This makes it trivial to match movies across the two files.
  2. Top-Level Merge: $file1 * $file2 merges the top-level fields—so producer from file2 is added, writer from file1 is preserved, and if there was a conflicting top-level field (like series), file2's value would override file1's (per your rule 1).
  3. Reconstruct Merged Movies Array: We combine the keys from both dictionaries to get all unique titles, then merge each corresponding movie object. This ensures:
    • year from file2 is added to each movie
    • actors from file1 is preserved
    • Any conflicting fields in a movie object would be overridden by file2 (rule 1)
    • Duplicate titles are automatically removed (rule 4)

Verification Against Your Expected Result

Running this command will produce:

{
  "series": "Harry Potter Movie Series",
  "writer": "J.K. Rowling",
  "producer": "David Heyman",
  "movies": [
    {
      "title": "Harry Potter and the Philosopher's Stone",
      "actors": [
        {
          "names": [
            "Emma Watson",
            "Other actor"
          ],
          "other": "Some value"
        }
      ],
      "year": "2001"
    },
    {
      "title": "Harry Potter and the Chamber of Secrets",
      "actors": [
        {
          "names": [
            "Emma Watson"
          ],
          "other": "Some value"
        }
      ],
      "year": "2002"
    }
  ]
}

(Note: Your expected result had a typo where "Chamber of Secrets" had year "2001"—this script correctly uses the 2002 value from file2.)

Why Your Previous Commands Failed

Commands like jq -s '.[0] * .[1]' or add treat arrays as atomic values—so when merging, the entire movies array from file2 replaces the one from file1, which is why you lost the actors data. The key is to merge the contents of the array, not the array itself.

All Rules Are Satisfied

  • Rule 1: File2 elements take priority (e.g., if a movie had a conflicting field in both files, file2's value would win)
  • Rule 2: File1-only fields like writer and movies[].actors are preserved
  • Rule 3: File2-only fields like producer and movies[].year are added
  • Rule 4: Unique title values are maintained, no duplicates

内容的提问来源于stack exchange,提问作者freljord

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 23:53:15