簡體   English   中英

sed regex查找和替換(歡迎awk解決方案)

[英]sed regex find & replace (awk solutions welcome)

我正在處理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

任何幫助,將不勝感激。 謝謝。

awk方法:

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

說明

當第一個字段匹配$1=="\\"CmteID\\""我們將第三個字段更改為期望的字符串,唯一可變的部分是CmteID value,分配給: \\n\\t\\"\\$id\\" : "$3"

添加了換行符(轉義char \\ )以提高代碼的清晰度。

結果

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

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,
....

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,
....

許多語言都有內置的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這樣的其他結構化數據格式一樣,對它使用文本替換會導致問題!

這可能對您有用(GNU sed):

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

這是一個過度引用的情況。 由於-r是有效的,因此不必要地引用了將$id分組的括號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM