コンマで区切られた文字列でkey = valueを見つけて置き換えるsedコマンドを作成しようとしています。
ファイルの文字列の例: KEY_1=value_1,KEY_2=value_2,SOMEKEY=lastValue
使用されたsedコマンド:
sed -r 's/KEY_2=.*?((?=,)|$)/KEY_2=new_value/' myFile.txt
キーが存在する場合は、キーとその値を新しいkey = valueに置き換えます。ほとんどの値はコンマ "," で終わりますが、文字列の最後の key=value には、がないことは例外です。
RedHat Linux VM では、次のエラーメッセージが表示されます。
sed: -e 式 #1, char 55: 前の正規表現が無効です。
私はこれが/ gで試した最後の「/」だと思います。これは、元の文字列でキーを繰り返すべきではないため、除外可能です。
答え1
このsed
ユーティリティはPerlと同様の正規表現をサポートしません。
代わりに、次のものを使用できます。
$ sed 's/KEY_2=[^,]*/KEY_2=new value/' file
KEY_1=value_1,KEY_2=new value,SOMEKEY=lastValue
または
$ sed 's/\(KEY_2\)=[^,]*/\1=new value/' file
KEY_1=value_1,KEY_2=new value,SOMEKEY=lastValue
または、次のようにawk
(正規表現を使用せずにキーと正確な文字列一致を使用すると、および両方がKEY_2
あるときに混乱を防ぐことができますSOME_OTHER_KEY_2
):
$ awk -F, -v OFS=, '{ for (i = 1; i <= NF; ++i)
if (split($i, a, "=") == 2 && a[1] == "KEY_2") {
$i = "KEY_2=new value"
break
} } 1' file
KEY_1=value_1,KEY_2=new value,SOMEKEY=lastValue
答え2
説明で述べたように、sed
PCREスタイルの正規表現はサポートされていません(参照:私の正規表現がXでは動作しますが、Yでは動作しないのはなぜですか?)。使用perl
できる
$ s='KEY_1=value_1,KEY_2=value_2,SOMEKEY=lastValue'
$ echo "$s" | perl -pe 's/KEY_2=.*?((?=,)|$)/KEY_2=new_value/'
KEY_1=value_1,KEY_2=new_value,SOMEKEY=lastValue
$ echo "$s" | perl -pe 's/SOMEKEY=.*?((?=,)|$)/SOMEKEY=new_value/'
KEY_1=value_1,KEY_2=value_2,SOMEKEY=new_value
正規表現を単純化できます。
$ # -l needed to prevent deleting the newline character for last field
$ echo "$s" | perl -lpe 's/KEY_2=\K[^,]+/new_value/'
KEY_1=value_1,KEY_2=new_value,SOMEKEY=lastValue
$ # to prevent partial match
$ echo "$s" | perl -lpe 's/(?<![^,])KEY_2=\K[^,]+/new_value/'
KEY_1=value_1,KEY_2=new_value,SOMEKEY=lastValue
バラよりperldoc コマンドスイッチここで使用されているコマンドラインオプションに関する注意事項