[英]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.