"
jsonを除いて\"
置き換える\
のに問題があります。\\
"
test.txt
入力ファイル
"a" "b"
{"1":"female","2":"197312","3":"359","4":"201109","5":"mail"}
\uff08\u524d\u5bfe\u5fdc
次のようなものを出力したい
\"a\" \"b\"
{"1":"female","2":"197312","3":"359","4":"201109","5":"mail"}
\\uff08\\u524d\\u5bfe\\u5fdc
答え1
より強力になるために、完全なjson解析を実行できます。
perl -0777 -pe '
s@(".*?"|\\)|(\{(?:"(?:\\.|[^"])*+"|(?2)|[^"{}]++)*+\})|[^{}\\"]+@
$1 ? $1 =~ s/["\\]/\\$&/gr : $&@gse'
どんな入力が同じですか?
"a" "b" "c{d"
{"1":"female","2":"197312","3":"359","4":"201109","5":"mail"}
{
"1": {"x": "y"}
"2": "}}}"
"3": ["{\"x", "}"]
}
\uff08\u524d\u5bfe\u5fdc
与えられた
\"a\" \"b\" \"c{d\"
{"1":"female","2":"197312","3":"359","4":"201109","5":"mail"}
{
"1": {"x": "y"}
"2": "}}}"
"3": ["{\"x", "}"]
}
\\uff08\\u524d\\u5bfe\\u5fdc
"foo\"bar"
入力にjsonオブジェクトが含まれている"foo\nbar"
場合、またはjsonオブジェクトの外部にある場合は、実行したい操作を明確にすることができます。
答え2
示した簡単な例では簡単です。次に始まらない行から文字をエスケープします{
。
$ sed -E '/^[^{]/s|(["\])|\\\1|g' file
\"a\" \"b\"
{"1":"female","2":"197312","3":"359","4":"201109","5":"mail"}
\\uff08\\u524d\\u5bfe\\u5fdc
ただし、JSONが複数行にまたがる可能性がある場合、状況はさらに複雑になります。この場合、{
オープンとクローズの数を計算し}
、その数が同じ場合(つまりJSON文字列にない場合)、置換を適用する小さなスクリプトを作成できます。それは次のとおりです。
perl -F'' -ne 'for (@F){$op++ if /{/; $cl++ if /}/; if($cl==$op){s|["\\]|\\$&|g;}print}' file
{
ただし、JSON文字列自体にJSON部分が含まれているか}
表示されていない場合(例:{"1":"b-{c}"}
またはその他)、問題が発生します。この場合は、以下を使用してください。スティーブンの方法代わりに。
答え3
$ sed 's/\(\\\|^"\|"$\|"[ \t]\)/\\\1/g' test.txt | sed 's/\([ \t]\)"/\1\\"/g'
\
"
行の始まり、行の終わり、またはスペース/タブの前または置換:
's/\(\\\|^"\|"$\|"[ \t]\)/\\\1/g'
- または
"
スペース/タブの背後:sed 's/\([ \t]\)"/\1\\"/g'
したがって、これはjson文字列にスペース/タブが含まれておらず、1行にある場合にのみ機能します。