awkを使用したリテラルバックスラッシュの置き換え

awkを使用したリテラルバックスラッシュの置き換え

以下を返すawsコマンドがあります。

{
    "Parameter": {
        "Name": "/mysite/development/mongodb_uri",
        "Type": "SecureString",
        "Value": "mongodb+srv://administrator:[email protected]/mysite_development?retryWrites=true&w=majority",
        "Version": 4
    }
}

awkでパイプして&シンボルをエスケープしたいです。

aws | awk '/Value/ { gsub(/[\",\"]/,\"\",\$2); gsub(/[\"&\"]/,\"\\\\&\",\$2); print \$2}'

結果は次のとおりです。

mongodb+srv://administrator:[email protected]/mysite_development?retryWrites=true&w=majority

ただし、&記号はエスケープされません。結果文字列に「\&」が表示されることが予想されます。このawkコマンドは、evalに渡されたシェルスクリプトの変数に保存されます。

AWS_COMMAND="aws ssm --region us-east-2 --with-decryption get-parameter --name"
AWK_COMMAND="awk '/Value/ { gsub(/[\",\"]/,\"\",\$2); gsub(/[\"&\"]/,\"\\\\&\",\$2); print \$2}'"

FETCH_AWS_SSM () {
  eval "$AWS_COMMAND /$APPLICATION/$DEPLOYMENT_GROUP_NAME/$1 | $AWK_COMMAND"
}

MONGODB_URI=$(FETCH_AWS_SSM "mongodb_uri")
echo MONGODB_URI

この文字通りのバックスラッシュをどのように取得できますか?

答え1

JSONを使用している場合は、そのために特別に設計されたツールを使用してください。jq:

$ aws | jq -r '.Parameter.Value | gsub("&";"\\&")' 
mongodb+srv://administrator:[email protected]/mysite_development?retryWrites=true\&w=majority

答え2

コマンドをシェル変数に保存してから評価しないでください。これにより、直接コーディングが難しくなり、セキュリティ上の問題が発生します。たとえば、(テストされていない)次の関数を代わりに使用します。

AWS_COMMAND() {
    aws ssm --region us-east-2 --with-decryption get-parameter --name "$@"
}

AWK_COMMAND() {
    awk '/Value/ { gsub(/[,"]/,"",$2); gsub(/&/,"\\\\&",$2); print $2 }'
}

FETCH_AWS_SSM() {
    AWS_COMMAND "/$APPLICATION/$DEPLOYMENT_GROUP_NAME/$1" | AWK_COMMAND
}

MONGODB_URI=$(FETCH_AWS_SSM 'mongodb_uri')
printf '%s\n' "$MONGODB_URI"

ただし、すべての関数名とエクスポートされていない変数名を小文字に変更します(スクリプト間の機能的な違いを強調するために単に置きました)。https://stackoverflow.com/questions/673055/ Correct-bash-and-shell-script-variable-capitalization

関連情報