4

次のjsonファイルがあります。

 { "last_modified": {
         "type": "/type/datetime", 
         "value": "2008-04-01T03:28:50.625462" }, 
     "type": { "key": "/type/author" }, 
     "name": "National Research Council. Committee on the Scientific and Technologic Base of Puerto Rico"s Economy.", 
     "key": "/authors/OL2108538A", 
     "revision": 1 }

名前の値には二重引用符があり、この二重引用符を一重引用符 (他の二重引用符ではなく) に置き換えたいだけです。どうすればいいですか?

4

7 に答える 7

3

単一の文字のすべての出現を置換したい場合は、trsed や awk よりも簡単なコマンドを使用することもできます。

   cat myfile.txt | tr \" \'

両方の引用符がエスケープされていることに注意してください。引用符以外の文字がある場合は、次のように記述します。

   cat myfile.txt | tr a A

編集: 質問が編集された後、この回答は無効になることに注意してください: Name プロパティ内の二重引用符だけでなく、すべての二重引用符を置き換えます。

于 2010-08-06T08:33:29.723 に答える
2

私は次のようなものを使用する方が良いと思いますsed

sed 's/"/'/g' ファイル

于 2010-08-06T08:33:12.727 に答える
1

入力に他の奇妙なエラーケースを追加する

{ "last_modified": {"type": "/type/datetime", "value": "2008-04-01T03:28:50.625462"},
  "type": {"key": "/type/author"},
  "name": "National Research Council. Committee on the Scientific and Technologic Base of Puerto Rico"s Economy.",
  "key": "/authors/OL2108538A",
  "revision": 1,
  "has \" escaped quote": 1,
  "has \" escaped quotes \"": 1,
  "has multiple " internal " quotes": 1,
}

文字列の実際の終了引用符の後にオプションの空白とコロン、コンマ、セミコロン、または中括弧のいずれかが続くというヒューリスティックを使用して、エスケープされていない内部二重引用符を修正するこのPerlプログラム

#! /usr/bin/perl -p

s<"(.+?)"(\s*[:,;}])> {
  my($text,$terminator) = ($1,$2);
  $text =~ s/(?<!\\)"/'/g;  # " oh, the irony!
  qq["$text"] . $terminator;
}eg;

次の出力を生成します。

$ ./fixdqs input.json
{"last_modified":{"type": "/ type / datetime"、 "value": "2008-04-01T03:28:50.625462"}、
  "type":{"key": "/ type / author"}、
  "名前": "国立研究評議会。プエルトリコの経済の科学技術基盤に関する委員会。"、
  "キー": "/ authors / OL2108538A"、
  「改訂」:1、
  「引用符をエスケープしました」:1、
  "引用符をエスケープしました\"":1
  「複数の「内部」引用符があります」:1、
}

入力から出力へのデルタ:

$ diff -ub input.json <(./ fixdqs input.json)
--- input.json
+++ / dev / fd / 63
@@ -1,9 +1,9 @@
 {"last_modified":{"type": "/ type / datetime"、 "value": "2008-04-01T03:28:50.625462"}、
   "type":{"key": "/ type / author"}、
-「名前」:「国立研究評議会。プエルトリコの経済の科学技術基盤に関する委員会。」、
+「名前」:「国立研究評議会。プエルトリコ経済の科学技術基盤に関する委員会。」、
   "キー": "/ authors / OL2108538A"、
   「改訂」:1、
   「引用符をエスケープしました」:1、
   "引用符をエスケープしました\"":1
-「複数の「内部」引用符があります」:1
+「複数の「内部」引用符があります」:1、
 }
于 2010-08-06T16:18:26.223 に答える
0

データが表示したとおりであり、余分な二重引用符が名前の値フィールドにのみ表示されると仮定します。

アップデート:

スクリプトを少し堅牢にしました(フィールド内の'、'の処理)。

BEGIN {
    q = "\""
    FS = OFS = q ", " q
}
{
    split($1, arr, ": " q)
    gsub(q, "'", arr[2])
    print arr[1] ": " q arr[2], $2, $3
}

このスクリプトをファイル(たとえばdequote.awk)に入れ、。を使用してスクリプトを実行します
awk -f dequote.awk input.json > output.json

アップデート2:

さて、あなたの入力は処理するのが非常に難しいです。私が考えることができる他の唯一のことはこれです:

{
    start = match($0, "\"name\": ") + 8
    stop = match($0, "\", \"key\": ")
    if (start == 8 || stop == 0) {
        print
        next
    }
    pre = substr($0, 1, start)
    post = substr($0, stop)
    name = substr($0, start + 1, stop - start - 1)
    gsub("\"", "'", name)
    print pre name post
}

説明:私は3つの部分に線を切り刻もうとします:

  1. 「名前」値フィールドの最初の二重引用符まで。
  2. 「名前」値フィールドから二重引用符を引いたもの。
  3. 最後の二重引用符と残りの行。

パート2では、すべての二重引用符を一重引用符に置き換えます。次に、3つのパーツを接着して、印刷します。

于 2010-08-06T08:59:02.757 に答える
0

の二重引用符のみを意味する場合は、次を使用できます'Rico"s'

sed "s/Rico\"s/Rico's/"

次のように:

pax> echo '{"name": "National Res...rto Rico"s Economy.", "key": "blah"}'
     | sed "s/Rico\"s/Rico's/"
{"name": "National Res...rto Rico's Economy.", "key": "blah"}
于 2010-08-06T08:40:26.177 に答える
0

「name」を引用符で囲んだだけの場合は、コマンドラインまたは bash スクリプトから sed を使用できます。

    sed -i 's/ "name"/ '\'name\''/g' filename.json

テスト済み、動作します。

于 2013-05-16T18:02:44.967 に答える
0
awk '{for(i=1;i<=NF;i++) if($i~/name/) { gsub("\042","\047",$(i+1)) }   }1' file
于 2010-08-06T14:01:34.877 に答える