2017-06-13 27 views
2

私は私が必要なものを、次の単純なJSONJQのすべての要素の空白をトリミングする方法は?

json='[{"k1":" http://url", "k2":null, "k3":" v3", "k4":" v4"}]' 

があります(v1v2の前にスペースなし)

"http://url",null 

私は何を持っていることは次のとおりです。

echo $json | jq -c '.[] | .k1, .k2 ' | paste -d "," - - 

k1のスペースを取り除く方法k2の値は?

+1

あなたは 'walk'機能を持っているのに十分JQ新しいを持っていますか? –

+1

btw、 'echo $ json'は実際にはちょっとバグです。もしあなたの空白で囲まれた' * 'があなたのテキストにあれば、それはファイル名のリストに置き換えられます。 $ json "'をエコーする方がずっと優れています。 –

+0

@CharlesDuffy最新の 'jq'バージョンがあります。 –

答えて

2

以下どこでも任意の複雑なJSON構造内部の文字列で先頭と末尾のスペースを削除します:

#!/usr/bin/env jq -cf 

# Define walk function (standard library only for jq 1.6 and newer, currently unreleased) 
def walk(f): 
    . as $in 
    | if type == "object" then 
     reduce keys_unsorted[] as $key 
     ({}; . + { ($key): ($in[$key] | walk(f)) }) | f 
    elif type == "array" then map(walk(f)) | f 
    else f 
    end; 

walk(
    if type == "string" then 
    (sub("^[[:space:]]+"; "") | sub("[[:space:]]+$"; "")) 
    else . end 
) 

つ(例えばtrim-jsonで)上記を保存し、その後、(chmod +x trim-json)実行可能ファイルをマークした場合./trim-json <<<"$json"あなたの与えられた入力を発する:同様

[{"k1":"v1","k2":"v2","k3":"v3","k4":"v4"}] 

、更新入力して:

$ json='[{"k1":" http://url", "k2":null, "k3":" v3", "k4":" v4"}]' 
$ ./trim-json <<<"$json" 
[{"k1":"http://url","k2":null,"k3":"v3","k4":"v4"}] 
+0

あなたのソリューションは素晴らしいですが、言及するのを忘れた新しい要件があります。これは 'null'または空の文字列' '' 'またはURLで動作する必要があります。私は質問を更新しました。 –

+0

このコードはすでにこれらのシナリオでは機能していませんか? –

+0

@AdamSiemion、...更新された入力で既存のコードを実行しました。編集に示されているように、それは完全に機能しました。 (あなたがなぜ要求された変更で私に戻ってきたのか、私は興味があります)。 –

0

あなたの例は規則的です。すべての値が不必要なスペースで始まるという点です。それは本当に代表だ場合、その範囲スライスにわたり、単純なマップが動作します:

$ jq -c '.[] | map_values(.[1:]) | .k1,.k2' <<< "$json" | paste -d "," - - 
"http://url",null 

このアプローチは、気取らないと理解するのは簡単であるという利点を持っています。あなたの例が0個以上の空白、入れ子配列などと一致しない場合は、gsub、条件文などを使用して、より包括的なアプローチを展開する必要があります。

+1

これは最初の文字を*何*かにかかわらず削除します。 *すべての文字列に先行スペースがあることが確実でない場合、それは...少し危険です。 –

3

入力はJSONオブジェクトの配列であり、あなたがワンライナーを探しているなら、次の要件を満たすように思われる場合:あなたの入力して

jq '.[]|(.k1,.k2)|if type=="string" then gsub("^\\s+|\\s+$";"") else . end' | paste -d "," - - 

、これは

を生成
"http://url",null 

nullが出力に表示される方法に柔軟性がある場合は、all-jqソリューション(つまり、pasteを含まない)も考慮する必要があります。例えば:あなたの入力して

jq -r '.[]|[.k1,.k2]|map(if type=="string" then gsub("^\\s+|\\s+$";"") else . end)|@csv' 

、これは生産:

"http://url", 
関連する問題