簡體   English   中英

使用 jq 和 awk 拆分大型 JSON 文件

[英]Split large JSON file by using jq and awk

我有一個大文件叫

Metadata_01.json

它由遵循以下結構的塊組成:

[
 {
  "Participant_id": "P04_00001",
  "no_of_people": "Multiple",
  "apparent_gender": "F",
  "geographic_location": "AUS",
  "ethnicity": "Caucasian",
  "capture_device_used": "iOS 14",
  "camera_orientation": "Portrait",
  "camera_position": "Side View",
  "indoor_outdoor_env": "Indoors",
  "lighting_condition": "Bright",
  "Occluded": 1,
  "category": "Two Person",
  "camera_movement": "Still",
  "action": "No action",
  "indoor_outdoor_in_moving_car_or_train": "Indoor",
  "daytime_nighttime": "Nighttime"
 },
 {
  "Participant_id": "P04_00002",
  "no_of_people": "Single",
  "apparent_gender": "M",
  "geographic_location": "AUS",
  "ethnicity": "Caucasian",
  "capture_device_used": "iOS 14",
  "camera_orientation": "Portrait",
  "camera_position": "Frontal View",
  "indoor_outdoor_env": "Outdoors",
  "lighting_condition": "Bright",
  "Occluded": "None",
  "category": "Animals",
  "camera_movement": "Still",
  "action": "Small action",
  "indoor_outdoor_in_moving_car_or_train": "Outdoor",
  "daytime_nighttime": "Daytime"
 },

依此類推……成千上萬。

我正在使用以下命令:

jq -cr '.[]' Metadata_01.json | awk '{print > (NR ".json")}'

它正在做預期的工作。

來自結構如下的大文件

我收到大量這樣命名的文件

和這樣的結構(一行)

而不是那些結果我需要每個 json 文件以“Participant_id”命名(例如 P04_00002.json)我想保留 json 結構看起來像每個文件

{
  "Participant_id": "P04_00002",
  "no_of_people": "Single",
  "apparent_gender": "M",
  "geographic_location": "AUS",
  "ethnicity": "Caucasian",
  "capture_device_used": "iOS 14",
  "camera_orientation": "Portrait",
  "camera_position": "Frontal View",
  "indoor_outdoor_env": "Outdoors",
  "lighting_condition": "Bright",
  "Occluded": "None",
  "category": "Animals",
  "camera_movement": "Still",
  "action": "Small action",
  "indoor_outdoor_in_moving_car_or_train": "Outdoor",
  "daytime_nighttime": "Daytime"
 }

我應該對上面的命令進行哪些調整才能實現這一目標? 或者也許有更簡單的方法來做到這一點? 謝謝!

我應該做哪些調整...?

我會 go 與:

jq -cr '.[] | (.Participant_id, .)' Metadata_01.json | awk '
  NR%2==1 {fn="id." $0 ".json"; next} {print >> fn; close(fn); }
'

然后運行類似jq. "$FILE" | sponge "$FILE" jq. "$FILE" | sponge "$FILE" jq. "$FILE" | sponge "$FILE"漂亮地打印每個文件。

或者,如果您可以解決 escaping 引號時可能出現的任何問題,您可以讓 awk 調用 jq:

jq -cr '.[] | (.Participant_id, .)' Metadata_01.json | awk -v q=$'\'' '
  NR%2==1 {fn = "id." $0 ".json"; next}
  {  system( ("jq . <<< " q $0 q " >> \"" fn "\"") );
     close(fn);
  }
'

“大數據”

當然,如果輸入文件對於jq empty來說太大或太慢,那么您將需要考慮替代方案,例如 jq 的--stream選項、 jstream或我自己的jm 例如,如果您希望 JSON 漂亮地打印在每個文件中:

while read -r json
do
   fn=$(jq -r .Participant_id <<< "$json")
   <<< "$json" jq . > "id.$fn.json"
done < <(jm Metadata_01.json)

建議使用 PowerShell,因為整體上處理對象往往更容易。 幸運的是,PowerShell 有一個ConvertFrom-Json cmdlet,您可以使用它來將返回的文本轉換為 PS object,讓您可以通過點符號 ( .Participant_id ) 引用屬性。 然后,您只需將每次迭代轉換回 JSON 格式並將其導出。 在這里,我使用New-Item創建帶有 output 的文件,但通過管道傳輸到Out-File也可以。

$json = Get-Content -Path '.\Metadata_01.json' -Raw | ConvertFrom-Json 
foreach ($json_object in $json)
{
    New-Item -Path ".\Desktop\" -Name "$($json_object.Participant_id).json" -Value (ConvertTo-Json -InputObject $json_object) -ItemType 'File' -Force
}

我可以看到您可能遇到的問題是 memory 不夠,由於該文件的大小,因為在此示例中您將首先保存到一個變量。 有很多解決方法,但這是出於演示目的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM