2017-08-10 6 views
0

jqを使用してシェルスクリプトプログラムでjsonファイルを解析しようとしています。私はiOSデベロッパだので、私は私が望むものを達成するであろうスウィフトコードのモック作品を書かれているJSONオブジェクトをシェルスクリプトのjqで繰り返します。

{ 
    "items":[ 
     { 
     "playlists":[ 
      { 
       "title":"Level One Title", 
       "courses":[ 
        { 
        "title":"Level One Course One Title", 
        "lessons":[ 
         { 
          "title":"lesson 1 title", 
          "url":"lesson 1 url" 
         }, 
         { 
          "title":"lesson 2 title", 
          "url":"lesson 2 url" 
         } 
        ] 
        }, 
        { 
        "title":"Level One Course Two Title", 
        "lessons":[ 
         { 
          "title":"lesson 1 title", 
          "url":"lesson 1 url" 
         }, 
         { 
          "title":"lesson 2 title", 
          "url":"lesson 2 url" 
         } 
        ] 
        } 
       ] 
      }, 
      { 
       "title":"Level Two Title", 
       "courses":[ 
        { 
        "title":"Level Two Course One Title", 
        "lessons":[ 
         { 
          "title":"lesson 1 title", 
          "url":"lesson 1 url" 
         }, 
         { 
          "title":"lesson 2 title", 
          "url":"lesson 2 url" 
         } 
        ] 
        }, 
        { 
        "title":"Level Two Course Two Title", 
        "lessons":[ 
         { 
          "title":"lesson 1 title", 
          "url":"lesson 1 url" 
         }, 
         { 
          "title":"lesson 2 title", 
          "url":"lesson 2 url" 
         } 
        ] 
        } 
       ] 
      } 
     ] 
     } 
    ] 
} 

JSONの構造は次のようになります。それは次のようになります。

for level in levels { 
    let title = level["title"] 
    //TODO: create a folder with title and set as pwd 
    for course in level["courses"] { 
     let courseTitle = course["title"] 
     //TODO: create a folder with title and set as pwd 
     for lesson in course["lessons"] { 
      let title = lesson["title"] 
      let videoURL = lesson["url"] 
      //TODO: download video in current folder with title 
     } 
    } 
} 

levelslevelがそれらDictionariesの一つであり、DictionariesArrayです。各レベルは、Arraycoursesを含み、それぞれDictionaryであり、Arraylesson辞書を含む。

Swiftから来て、jqの構文が非常に混乱していることがわかりました。特に、関数の戻り値を変数に代入しました。ここまでです。

levels=$(jq ".items[0].playlists" data.json) 
for level in $levels 
do 
    title=$($level | jq ".title") 
    echo $title 
done 

これはまったく動作していないようです。私はfor-loopsを使用する私のロジックが完全に間違っていると思います。どのようにこれが行われる任意のアイデアですか?

+1

サンプル入力とサンプル出力を提供すると役に立つので、コードを読む必要はありません。また、コードから作成するのが難しい文脈があります(トップレベル 'レベル'リストや辞書など?) –

+0

一般に、 'jq'を呼び出すプログラムはすべての反復を行います。つまり、ループはシェルスクリプトではなくjqコード内になければなりません。 –

+0

(と 'レベルの$ levels'はシェルとしてバグです - http://mywiki.wooledge.org/DontReadLinesWithForを参照してください) –

答えて

2

明確なシェル変数にタイトルとURLを抽出するためのコードのように見えることがあります。

ここ
jq_program=' 
.items[].playlists[]   # we only care about playlist contents 
| .title as $level_title  # store the level title before recursing 
| .courses[]     # ...into elements of the array in .courses... 
| .title as $course_title  # repeat to store the course title 
| .lessons[]     # ...before recursing into the lesson... 
# ...and emitting the stored level and course titles, plus the lesson title and url 
| [$level_title, $course_title, .title, .url] | @tsv        
' 

while IFS=$'\t' read -r level_title course_title lesson_title lesson_url <&3; do 
    mkdir -p -- "$level_title/$course_title" 
    ## For test purposes, just store the URL in the file 
    printf '%s\n' "$lesson_url" >"$level_title/$course_title/$lesson_title" 
    ## If we had real data, we might instead be running something like: 
    # curl -o "$level_title/$course_title/$lesson_title" "$lesson_url" 
done 3< <(jq -r "$jq_program" <input.json) 

、我々はフラット(タブ区切り)リストを再帰的と発光の仕事をjqやっている、と読んでいますbashのそのリスト明らかな理由から、コンテンツにタブを含めることができない場合にのみ動作します。任意の文字列(bashが格納できる範囲内)で作業する必要がある場合は、jqからNUL区切りの出力を生成することができますが、stedolan/jq#1271で説明した回避策の1つが必要です。

の出力からタブ区切りのデータを読み取るためにここで使用している技術について、BashFAQ #1を参照してください。

+0

各コースに「レッスン」レイヤーがありません。また、リストに名前は必要ありません.JSONと同様のフォルダ構造を作成する必要があります。 – damjandd

+1

@ damjandd、シェルスクリプトの 'mkdir'を参照してください。これはJSONからディレクトリ構造を作成し、jqによって生成されたリストから読み込み、 'curl'はそのディレクトリにダウンロードしています。 –

+0

@CharlesDuffy申し訳ありませんが、私はそれを逃しました。 – damjandd

関連する問題