質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

2回答

1569閲覧

bashでJSONデータを置換できない

Linkey

総合スコア77

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

1クリップ

投稿2018/01/17 13:59

以下のようなJSONが記載されているテキストファイルをシェルスクリプト(bash)を使って内容を書き換えようとしています。

JSON

1{ 2 "apple":"sweet", 3 "money":"20000", 4 { 5 6 "hoge":"hoge", 7 "aaaa":"bbbb", 8 "sample":{ 9 "profile":{ 10 "name":"hoge", 11 "age":"28", 12 "nationality":"Japan" 13 }, 14 "hobby":{ 15 "music":"rock", 16 "sports":"baseball" 17 }, 18 "CCC":[ 19 { 20 "test":"sample", 21 "sample":"hogehoge" 22 }, 23 { 24 "hogehoge":"bbbb", 25 "xxxxx":"yyyyy" 26 } 27 ], 28 "friends":[ 29 { 30 "name":"Jane", 31 "age":"23", 32 "sex":"female", 33 "nationality":"America" 34 }, 35 { 36 "name":"Lee", 37 "age":"19", 38 "sex":"male", 39 "nationality":"China" 40 } 41 ] 42 } 43 }, 44 "last":"final" 45}

具体的に以下の部分をsedコマンドを使って書き換えようとしています。

JSON

1 "sample":{ 2 "profile":{ 3 "name":"hoge", 4 "age":"28", 5 "nationality":"Japan" 6 }, 7 "hobby":{ 8 "music":"rock", 9 "sports":"baseball" 10 }, 11 "CCC":[ 12 { 13 "test":"sample", 14 "sample":"hogehoge" 15 }, 16 { 17 "hogehoge":"bbbb", 18 "xxxxx":"yyyyy" 19 } 20 ], 21 "friends":[ 22 { 23 "name":"Jane", 24 "age":"23", 25 "sex":"female", 26 "nationality":"America" 27 }, 28 { 29 "name":"Lee", 30 "age":"19", 31 "sex":"male", 32 "nationality":"China" 33 } 34 ] 35 }

スクリプトは以下のような処理を実装しました。

bash

1#!/ bin/bash 2 3updateSample="\"sample\":{\"profile\":{\"name\":\"Tommy\",\"age\":\"24\",\"nationality\":\"Canada\"},\"hobby\":{\"music\":\"pop\",\"sports\":\"tennis\"}, \"CCC\":[{\"test\":\"sample\",\"sample\":\"hogehoge\"},{\"hogehoge\":\"bbbb\",\"xxxxx\":\"yyyyy\"}], \"friends\":[{\"name\":\"King\",\"age\":\"44\",\"sex\":\"male\",\"nationality\":\"Turkey\"},{\"name\":\"John\",\"age\":\"33\",\"sex\":\"male\",\"nationality\":\"America\"},{\"name\":\"Lala\",\"age\":\"10\",\"sex\":\"female\",\"nationality\":\"India\"}]}" 4 5 6#sample以降の情報を取得する 7cmdExeResult=$(cat test.txt | awk '{print substr($0, index($0, "¥"sample"))}') 8#不要な部分を取り除く("last"以降) 9cmdExeResult=$(echo ${cmdExeResult} | awk '{ sub("},¥"last.*", ""); print $0;}') 10#データを置換する 11sed -i -e "s/$cmdExeResult/$updateSample/g" test.text 12

作成したシェルを動かして見たところ、以下のようなエラーが出てしまいました。
sed: -e expression #1, char 6: unterminated `s' command

メタ文字が入っているのが原因かなと思い、解決策を探していますがなかなかうまくできません。
そもそも置換する条件に誤りがあるのでしょうか?

シェルスクリプトやlinuxコマンドに詳しい方がいましたらご回答いただけないでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

最初に、質問文にある JSON が Key:Value ペアとしての形式を保っていないので、以下のように records を足した JSON をサンプルとして用います

json

1{ 2 "apple": "sweet", 3 "money": "20000", 4 "records": { 5 "hoge": "hoge", 6 "aaaa": "bbbb", 7 "sample": { 8 "profile": { 9 "name": "hoge", 10 "age": "28", 11 "nationality": "Japan" 12 }, 13 "hobby": { 14 "music": "rock", 15 "sports": "baseball" 16 }, 17 "CCC": [ 18 { 19 "test": "sample", 20 "sample": "hogehoge" 21 }, 22 { 23 "hogehoge": "bbbb", 24 "xxxxx": "yyyyy" 25 } 26 ], 27 "friends": [ 28 { 29 "name": "Jane", 30 "age": "23", 31 "sex": "female", 32 "nationality": "America" 33 }, 34 { 35 "name": "Lee", 36 "age": "19", 37 "sex": "male", 38 "nationality": "China" 39 } 40 ] 41 } 42 }, 43 "last": "final" 44} 45

records の中の sample を抜き出したい(?)ので、jq コマンドを用いて以下のように記述し、結果を得ます

sh

1jq .record.sample data.json

json

1{ 2 "profile": { 3 "name": "hoge", 4 "age": "28", 5 "nationality": "Japan" 6 }, 7 "hobby": { 8 "music": "rock", 9 "sports": "baseball" 10 }, 11 "CCC": [ 12 { 13 "test": "sample", 14 "sample": "hogehoge" 15 }, 16 { 17 "hogehoge": "bbbb", 18 "xxxxx": "yyyyy" 19 } 20 ], 21 "friends": [ 22 { 23 "name": "Jane", 24 "age": "23", 25 "sex": "female", 26 "nationality": "America" 27 }, 28 { 29 "name": "Lee", 30 "age": "19", 31 "sex": "male", 32 "nationality": "China" 33 } 34 ] 35}

詳しくはわからないのですが、この問題に対する解決策は、正規表現ではなく、構文解析の出番なのかもしれません

詳しい使い方については man jq や、公式のマニュアルを参照してみてください

何か参考になれば幸いです

Links

投稿2018/01/17 15:14

gouf

総合スコア2321

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Linkey

2018/01/18 14:22

参考にさせていただきます
guest

0

ベストアンサー

jsonデータ内の[が正規表現のメタ文字扱いとなってしまうためこれでは置換がうまく行かないでしょう。
awkをどうせ使うなら、始めから終わりまでawkで処理した方が遥かに効率的だと思います。ちゃんとチェックしていませんけど、雰囲気としてはこんな感じで。

awk

1BEGIN{ 2 updateSample="\"sample\":{\"profile\":{\"name\":\"Tommy\",\"age\":\"24\",\"nationality\":\"Canada\"},\"hobby\":{\"music\":\"pop\",\"sports\":\"tennis\"}, \"CCC\":[{\"test\":\"sample\",\"sample\":\"hogehoge\"},{\"hogehoge\":\"bbbb\",\"xxxxx\":\"yyyyy\"}], \"friends\":[{\"name\":\"King\",\"age\":\"44\",\"sex\":\"male\",\"nationality\":\"Turkey\"},{\"name\":\"John\",\"age\":\"33\",\"sex\":\"male\",\"nationality\":\"America\"},{\"name\":\"Lala\",\"age\":\"10\",\"sex\":\"female\",\"nationality\":\"India\"}]}" 3} 4 5{ 6 t = t $0 "\n" 7} 8 9END{ 10 t1 = substr(t, index(t, "\"sample")) 11 sub("},\"last.*", "", t1) 12 gsub("\[", "\[", t1) 13 gsub(t1, updateSample, t) 14 print(t) 15} 16 17# awk -f test.awk test.text

投稿2018/01/17 15:09

KojiDoi

総合スコア13669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Linkey

2018/01/18 14:22

ありがとうございます。参考にさせていただきます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問