動的エスケープ変数

動的エスケープ変数

"name":特定の正規表現構造に一致するようにpackage.jsonファイルのフィールドを自動的に設定する名前ヘルパースクリプトを作成していますが、実際に名前を設定する際にいくつかの問題があります。一致する必要がある正規表現はです'\@abc\/([a-z]+-{0,1})+[a-z]*$'

今は基本的にこれを行います(命名規則に準拠していることを実際に確認するためのいくつかの追加作業も行います)。

pattern='\@abc\/([a-z]+-{0,1})+[a-z]*$'
if [[ ! $name =~ $pattern ]]; then 
  read -rp "New name: " newName
  sed -ri "s/(\s.\"name\"\:\s\").*/\1$newName\",/g" $1/package.json
fi

ご覧のとおり、ここでの問題は、変数が$newNamesedからコマンドとして処理されることです。これにはエスケープ文字が必要です(ユーザーが実際に正しい構造に新しい名前を書いたと仮定します)。これを行う方法はありますか?可能な限り依存関係がないことが最善です。

ベストアンサー1

一見すると、この質問は重複した質問です。「sed」置換に挿入された文字列がすべてのメタ文字をエスケープするかどうかを確認する方法。ただし、JSONは行sed中心のテキスト操作ツールですが、JSONは行中心ではなく構造化文書形式です。したがって、sed「特定の方法で使用したい」という部分ではなく、「JSON文書を使用したい」という部分を問題として解決することをお勧めします。


これはJSONに関連しているのでjq

jq --arg newname '@abc/corrected-name' \
    'select( .name | test("^@abc/([a-z]-?)+[a-z]*$") | not ).name |= $newname' file.json

このコマンドは、入力がname最上位キーを持つJSON文書で構成されていると仮定します。 (おそらく)入力文書を修正し、結果を標準出力に書き込みます。

簡単に言えば、このjq式はname、入力セット内の値が次のような最上位キーを持つすべての要素を選択します。いいえマッチ^@abc/([a-z]-?)+[a-z]*$。要素を選択すると、対応するキーname値がの値で更新されます$newvalue

この方法の利点は、式にシェル変数を挿入する必要がなく、$newname内部変数に割り当てられた値が自動的にJSONにエンコードされることですjq(特定の方法でエンコードする必要がある場合)。

などの書類を入力してください。

{
  "name": "@abc/abc-foo"
}

コマンドは変更されずに残ります。

{
  "name": "bumblebee"
}

なります

{
  "name": "@abc/corrected-name"
}

おすすめ記事