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

如果要替换所有出现的单个字符,还可以使用命令tr,比 sed 或 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 输入.json
{ "last_modified": {"type": "/type/datetime", "value": "2008-04-01T03:28:50.625462"},
  "type": {"key": "/type/author"},
  "名称": "国家研究委员会。波多黎各经济科技基础委员会。",
  "key": "/authors/OL2108538A",
  “修订”:1,
  "有 \" 转义引号": 1,
  "有 \" 转义引号 \"": 1,
  "有多个 ' 内部 ' 引号": 1,
}

从输入到输出的增量:

$ diff -ub input.json <(./fixdqs input.json)
--- 输入.json
+++ /dev/fd/63
@@ -1,9 +1,9 @@
 { "last_modified": {"type": "/type/datetime", "value": "2008-04-01T03:28:50.625462"},
   "type": {"key": "/type/author"},
- “名称”:“国家研究委员会。波多黎各经济科技基础委员会。”,
+“名称”:“国家研究委员会。波多黎各经济科技基础委员会。”,
   "key": "/authors/OL2108538A",
   “修订”:1,
   "有 \" 转义引号": 1,
   "有 \" 转义引号 \"": 1,
- "有多个 " 内部 " 引号": 1,
+ "有多个 ' 内部 ' 引号": 1,
 }
于 2010-08-06T16:18:26.223 回答
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

假设您的数据与您显示的完全相同,并且额外的双引号仅出现在名称值字段中:

更新:

我使脚本更加健壮(处理 ', ' 内部字段)。

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
}

解释:我试着把这条线分成三个部分:

  1. 直到“名称”值字段的第一个双引号;
  2. “名称”值字段减去双引号;
  3. 结束双引号和该行的其余部分。

在第 2 部分中,我将所有双引号替换为单引号。然后我把这三个部分粘在一起并打印出来。

于 2010-08-06T08:59:02.757 回答
0

如果只是“名称”周围的引号,那么您可以从命令行或 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 回答