sed regex find&替换(awk解决方案欢迎)

时间:2015-12-09 21:39:59

标签: regex awk sed

我正在处理JSON文件(对于MongoDB),需要将字段名称转换为数据库引用。我尝试通过sed尝试(虽然我打开使用awk的解决方案等),但我是一个完整的菜鸟工具并且正在努力。

输入:

...
"FECTransID" : 4030720141206780377,
"CID" : "N00031103",
"CmteID" : "C00465971",
"RecipCode" : "RW",
"Amount" : 500,
....

需要输出:

...
"FECTransID" : 4030720141206780377,
"CID" : "N00031103",
"CmteID" : {
    "ref" : "Cmtes",
    "$id" : "C00278101",
    "$db" : "OpenSecrets"
},
"RecipCode" : "RW",
"Amount" : 500,
....

我的sed命令尝试是:

sed -r 's/\"CmteID\" \: \(\"[\w\d]\{9\}\",\)/\"CmteID\" : { \
                \"ref\" : \"Cmtes\", \
                \"$id\" : \1 \
                \"$db\" : \"OpenSecrets\" \
            }/' <IN_FILE >OUT_FILE

但是当我运行它时出现此错误:

sed: -e expression #1, char 198: invalid reference \1 on `s' command's RHS

任何帮助将不胜感激。感谢。

5 个答案:

答案 0 :(得分:2)

awk方法:

awk '$1=="\"CmteID\"" {$3="{\n\t\"ref\" : \"Cmtes\",\
                            \n\t\"\$id\" : "$3"\
                            \n\t\"\$db\" : \"OpenSecrets\"\n},"}1' infile

<强>解释

当第一个字段匹配$1=="\"CmteID\""时,我们正在更改预期字符串的第三个字段,唯一的变量部分是CmteID值,分配在:\n\t\"\$id\" : "$3"

添加换行符(转义字符\)以提高代码的清晰度。

<强>结果

"FECTransID" : 4030720141206780377,
"CID" : "N00031103",
"CmteID" : {
    "ref" : "Cmtes",                    
    "$id" : "C00465971",                    
    "$db" : "OpenSecrets"
},
"RecipCode" : "RW",
"Amount" : 500,

答案 1 :(得分:1)

awk救援!

$ awk '$1=="\"CmteID\""{print $1 ": {"; 
                         print "\t\"ref\" : \"Cmtes\","; 
                         print "\t\"$id\" : "$3;
                         print "\t\"$db\" : \"OpenSecrets\",";
                         print "},";
                         next}1' jsonfile

...
"FECTransID" : 4030720141206780377,
"CID" : "N00031103",
"CmteID": {
        "ref" : "Cmtes",
        "$id" : "C00465971",
        "$db" : "OpenSecrets",
},
"RecipCode" : "RW",
"Amount" : 500,
....

进行一些清理

$ awk -v NT="\n\t" 'function q(x) {return "\""x"\"";}; 
       $1==q("CmteID") {$3 = " {" 
                     NT q("ref") " : " q("Cmtes") "," 
                     NT q("$id") " : " $3 
                     NT q("$db") " : " q("OpenSecrets") 
                     ",\n},"}1' jsonfile
...
"FECTransID" : 4030720141206780377,
"CID" : "N00031103",
"CmteID" :  {
        "ref" : "Cmtes",
        "$id" : "C00465971",
        "$db" : "OpenSecrets",
},
"RecipCode" : "RW",
"Amount" : 500,
....

答案 2 :(得分:1)

sed用于单个行上的简单替换,即全部。这个问题不是那样的,所以这不是sed的工作。

$ cat tst.awk
BEGIN { FS=OFS=" : " }
$1 == "\"CmteID\"" {
    print $1, "{"
    print "   \"ref\"", "\"Cmtes\""
    print "   \"$id\"", $2
    print "   \"$db\"", "\"OpenSecrets\""
    $0 = "},"
}
{ print }

$ awk -f tst.awk file
...
TransID" : 4030720141206780377,
"CID" : "N00031103",
"CmteID" : {
   "ref" : "Cmtes"
   "$id" : "C00465971",
   "$db" : "OpenSecrets"
},
"RecipCode" : "RW",
"Amount" : 500,
....

答案 3 :(得分:0)

许多语言都内置了JSON解析器。 PHP就是其中之一:

#!/usr/bin/php
<?php
$infile = $argv[1];
$outfile = $argv[2];
$data = json_decode(file_get_contents($infile));
$id = $data["CmteID"];
$data["CmteID"] = array("ref"=>"Cmtes", "\$id"=>$id, "\$db"=>"OpenSecrets");
file_put_contents($outfile, json_encode($data));

未经测试但它应该有效。使其可执行并调用./myscript.php IN_FILE OUT_FILE

我的主要观点是,JSON不是文本,使用文本替换可能会导致问题,就像其他结构化数据格式(如XML)一样!

答案 4 :(得分:0)

这可能适合你(GNU sed):

sed -r 's/"CmteID" : (.*)/"CmteID" : { \
            "ref" : "Cmtes", \
            "$id" : \1 \
            "$db" : "OpenSecrets" \
        },/' fileIn >fileOut

这是一个过度引用的案例。由于$id生效,因此-r分组的parens已被不必要地引用。