web-dev-qa-db-ja.com

シェル:単語を見つけて置き換える

シェルスクリプトに固定形式の文字列があります:'[STATUS REPORT] PROJECT'。ユーザーが私のシェルスクリプトを実行すると、'PROJECT'の値を指定するように求められます。

Word 'PROJECT'をユーザー提供値に置き換えたいと思います。たとえば、'ABCD'がユーザー入力の場合:

「[ステータスレポート] ABCD」

私には2つの問題があります:1:プロジェクト名の「&」のような特殊文字にどのように取り組むか?例:

echo "[STATUS REPORT] PROJECT" |  awk '{ gsub(/PROJECT/, "A&A"); print }' 

次の出力が得られます。

【ステータスレポート】APROJECTA

2:私の実際のシェルステートメントは次のようになります。

echo "[STATUS REPORT] PROJECT" |  awk '{ gsub(/PROJECT/, $ProjectName); print }'

ここで、$ ProjectNameは、ユーザーが指定したプロジェクト名を格納します。しかし、これはうまくいかないようです

どうすればこれを正しく機能させることができますか?

2
smokinguns

これにより、最初の問題が解決します。

echo "[STATUS REPORT] PROJECT" |  awk '{ gsub(/PROJECT/, "A\\&A"); print }'

&はawk置換の特殊文字です。これは「一致したもの」を意味します。\を使用する場合はエスケープする必要があります。awk文字列を使用しているため、\エスケープとして1つを生成するには2\を入力する必要があります。 \nのような次の文字。)

これにより、2番目の問題が解決します。

ProjectName=toto
echo "[STATUS REPORT] PROJECT" |  awk -v "ProjectName=$ProjectName" '{ gsub(/PROJECT/, ProjectName); print }'

編集"の周りに新しく追加されたProjectName=$ProjectNameに注意して、ProjectNameのスペースがスクリプトを壊さないようにします。)

しかし、awkは文字列置換を実行するための大きなツールなので、sedを使用することをお勧めします。

echo "[STATUS REPORT] PROJECT" |  sed -e 's/PROJECT/A\&A/'
ProjectName=toto;
echo "[STATUS REPORT] PROJECT" |  sed -e "s/PROJECT/${ProjectName//\//\\/}/"

編集ProjectName/は最初の解決策を壊していました。スラッシュのエスケープを追加しましたが、他のいくつかの文字はまだそれを壊しています:&\1、.. 。プレーンバッシュシェルベローズの方が安全だと思います。)

またはプレーンbashシェル:

msg="[STATUS REPORT] PROJECT"
echo ${msg//PROJECT/A&A}
ProjectName=toto
echo ${msg//PROJECT/$ProjectName}
5
jfg956

(申し訳ありませんが、ここにはコメント権限がありません)

投稿したスニペットから、文字列をawkにパイプする必要がある理由はあまり明確ではありません。

echoステートメント内で変数を使用するだけで、bashが変数を置き換えます。

echo "[STATUS REPORT] $ProjectName"
3
Nithin Philips