2016-04-27 12 views
0

_のJSONファイルのキー名にあるハイフン文字-を、キーと値のペアの値側に影響を与えずに置き換えようとしています。sedを使用してパターン間で文字を置き換える方法

例入力:

{ 
    "outcome": "failed", 
    "failure-description": "ra ra ra - and more", 
    "rolled-back": true 
} 

は、sedを使ってこれを実行する方法はありますか?それは一致するパターンかもしれませんが、sedは"(.*[^"])":の間だけを置き換えますが、一致した部分文字列内の不要な文字を置き換える方法を考え出すことができませんでした。

期待される結果は次のようになります。

{ 
    "outcome": "failed", 
    "failure_description": "ra ra ra - and more", 
    "rolled_back": true 
} 
+0

をシンプル 'sedのさん/ -/_/''働くだろう - おそらく、このようなハイフンだけのようにさらにいくつかの例を追加値、キーの複数のハイフンなど? –

答えて

0

これは動作します:

$ sed 's/-\([^:]*\):/_\1:/' infile 
{ 
    "outcome": "failed", 
    "failure_description": "ra ra ra - and more", 
    "rolled_back": true 
} 

これは、コロン以外の文字を撮影した一連続い-を探し、その後、結腸;ハイフンをアンダースコアで置き換え、キャプチャしたグループとコロンを元に戻します。

この制限は、最初のハイフンのみを置き換えることです。コロンの前にすべてのハイフンを置き換えるに

{ 
    "outcome": "failed", 
    "failure-description": "ra ra ra - and more", 
    "two-hyphens-here": "ra ra ra - and more", 
    "rolled-back": true 
} 

、我々は条件分岐を使用することができます:私たちの入力は次のようになりますと仮定し

$ sed ':a;s/-\([^:]*\):/_\1:/;ta' infile 
{ 
    "outcome": "failed", 
    "failure_description": "ra ra ra - and more", 
    "two_hyphens_here": "ra ra ra - and more", 
    "rolled_back": true 
} 

これは、ラベル(:a)を設定し、にt命令(分岐を使用していますパターンスペースが変更されている場合はラベル)。 BSDの場合

は、Mac OSに見られるように、ラベルは別々のコマンドでなければならないのsed:

このすべての固有の制限が引用符との間にコロンがあってはならないということであることを
sed -e ':a' -e 's/-\([^:]*\):/_\1:/;ta' infile 

お知らせこの種の操作を行うには、通常、jqなどの適切なJSONパーサを使用することをお勧めします。

+0

Benjamin氏に感謝します。条件付き分岐は入れ子構造のjson構造でも機能します。 – Niels

0

拡張正規表現と括弧構造を使用します。

-r, --regexp-extended 
    use extended regular expressions in the script. 

これは正しい結果が得られますが、いくつかの調整が誤った一致に対して、正規表現を強化するために必要とされ得る:

sed -re 's/([:alpha:]*)[-]([:alpha:]*)/\1_\2/' 

結果:単純な式が与えられたことを

{ 
    "outcome": "failed", 
    "failure_description": "ra ra ra - and more", 
    "rolled_back": true 
} 

注意値の側にパターンが含まれている場合、上記の値は不十分です。データセットを調べ、必要に応じてカッコで囲まれた式や参照を追加して、マッチをより緊密に固定します。カッコで囲まれた式をネストすることは可能ですが、逆参照を決定するのは複雑です。

$ sed --version 
GNU sed version 4.1.5 
0

ちょうどawkを使用します、示さ入力について

$ awk 'BEGIN{FS=OFS="\": \""} {gsub(/-/,"_",$1)} 1' file 
{ 
    "outcome": "failed", 
    "failure_description": "ra ra ra - and more", 
    "rolled_back": true 
} 
関連する問題