Shell:查找和替换单词

smo*_*uns 2 bash awk shell-script string-manipulation

我的 shell 脚本中有一个字符串,它采用固定格式:'[STATUS REPORT] PROJECT'. 当用户执行我的 shell 脚本时,他会被要求提供'PROJECT'.

我想'PROJECT'用用户提供的价值替换这个词。例如,如果'ABCD'是用户输入:

'[状态报告] ABCD'

我有两个问题: 1:如何处理项目名称中的“&”等特殊字符?例如:

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

我得到以下输出:

[状态报告] APROJECTA

2:我的实际 shell 语句如下所示:

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

其中 $ProjectName 存储用户提供的项目名称。但这似乎不起作用

我怎样才能让它正常工作?

jfg*_*956 5

这将解决您的第一个问题:

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

(&是 awk 替换中的一个特殊字符:它的意思是“已匹配的内容”。如果使用 a ,则需要转义\。当您在 awk 字符串中时,您需要输入 2\来生成一个作为\转义下一个字符,如\n.)

这将解决您的第二个问题:

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

编辑:注意"周围新添加的内容,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//\//\\/}/"
Run Code Online (Sandbox Code Playgroud)

编辑:一个/in ProjectNamewill 破坏了最初的解决方案。我添加了斜杠的转义,但其他一些字符仍然会破坏它:&, \1, ...我认为下面的普通 bash shell 更安全。)

或在普通的 bash shell 中:

msg="[STATUS REPORT] PROJECT"
echo ${msg//PROJECT/A&A}
ProjectName=toto
echo ${msg//PROJECT/$ProjectName}
Run Code Online (Sandbox Code Playgroud)