这个 bash 脚本给了我任务来解决并将关键字替换为#Expected result 但是我运行脚本时显示的错误如下 (cat: demo.txt: 没有这样的文件或目录)
创建名为 demo.txt 的文件,内容如下。
# demo.txt
AAA=demo-73
XXX=
YYY=
ZZZ=demo-11674
#!/usr/bin/env bash
# script.sh
function findAndReplace() {
KEYWORD=$1
REPLACED_KEYWORD=$2
FILE=$3
SearchResults=$(grep -w ${KEYWORD} ${FILE} | wc -l)
if [ "${SearchResults}" != 0 ]; then
sed -i 's^'${KEYWORD}'.*^'${KEYWORD}'='${REPLACED_KEYWORD}^'' "${FILE}"
else
exit 1
fi
}
## EXECUTE METHOD
BUILD_NUMBER="123"
# EXCUTION FORMAT FIRST SEARCH KEYWORD, REPLACED_KEYWORD AND TRAGET FILE NAME
findAndReplace "XXX" "demo-${BUILD_NUMBER}" "demo.txt"
findAndReplace "YYY" "yyy-${BUILD_NUMBER}" "demo.txt"
预期结果
AAA=demo-73
XXX=demo-123
YYY=yyy-123
ZZZ=demo-11674
答案1
没有办法的错误:
cat: demo.txt: No such file or directory
源自该脚本,因为该cat
命令未在脚本中使用...我可以想象一个错误来自grep
:
grep: demo.txt: No such file or directory
如果文件demo.txt
不在运行该脚本的同一目录中,则有可能,即您需要先到cd
包含该文件的目录demo.txt
,然后从那里运行脚本,或者您需要demo.txt
在函数的参数中设置该文件的完整路径。
除非,你还可以demo.txt
使用这里的文件语法与cat
(cat: demo.txt: No such file or directory
如果使用不当,可能会导致错误)...正确的方法如下:
cat << EOF > demo.txt
AAA=demo-73
XXX=
YYY=
ZZZ=demo-11674
EOF
否则,您已经付出了巨大的努力来编写脚本,它应该能够按预期工作...... 有一些小的评论:
grep
-c
如果给出如下选项,它本身就可以计算行数:SearchResults=$(grep -c "${KEYWORD}" "${FILE}")
在命令中使用变量时,请用双引号括起来,以防止出现通配符和单词拆分。
因此你的脚本看起来将会像这样:
#!/usr/bin/env bash
# script.sh
function findAndReplace() {
KEYWORD=$1
REPLACED_KEYWORD=$2
FILE=$3
SearchResults=$(grep -c "${KEYWORD}" "${FILE}")
if [ "${SearchResults}" != 0 ]; then
sed -i 's^'"${KEYWORD}"'.*^'"${KEYWORD}"'='"${REPLACED_KEYWORD}"^'' "${FILE}"
else
exit 1
fi
}
## EXECUTE METHOD
BUILD_NUMBER="123"
# EXCUTION FORMAT FIRST SEARCH KEYWORD, REPLACED_KEYWORD AND TRAGET FILE NAME
findAndReplace "XXX" "demo-${BUILD_NUMBER}" "demo.txt"
findAndReplace "YYY" "yyy-${BUILD_NUMBER}" "demo.txt"
另外,不要使用全大写的变量名,因为 shell 保留的变量名也是全大写的,以避免冲突。
值得一提的是(特别感谢@steeldriver)如果你的目的只是验证是否存在匹配,那么你实际上并不需要计算匹配的行数(
if [ "${SearchResults}" != 0 ]; then
显然,这是因为)...您可以改为依赖grep
s 退出状态,该-q
选项不会将任何内容写入标准输出,并且会立即以零退出(即成功) 状态,如果找到任何匹配项,即使检测到错误,即grep -q --
...--
将指示 s 选项的结束grep
,并防止在以下模式以破折号开头的情况下出现错误(-
)... 因此 if 语句看起来应如下所示:if grep -q -- "${KEYWORD}" "${FILE}"; then
还将
sed
尝试从给定的文件中匹配和替换,例如,demo.txt
无论它是否实际包含搜索模式...它只会在模式匹配时进行替换,否则跳过...它还将以零退出(成功sed
)是否找到匹配项并进行替换...在处理带有选项的文件时唯一需要关注的-i
是它将修改其时间戳...如果这不是一个问题,那么您的脚本可以很简单(如果位置参数可以进一步简化$1
,$2
并直接在命令$3
中使用sed
) 作为:
#!/bin/bash
function findAndReplace() {
KEYWORD=$1
REPLACED_KEYWORD=$2
FILE=$3
sed -i 's^'"${KEYWORD}"'.*^'"${KEYWORD}"'='"${REPLACED_KEYWORD}"^'' "${FILE}"
}
## EXECUTE METHOD
BUILD_NUMBER="123"
# EXCUTION FORMAT FIRST SEARCH KEYWORD, REPLACED_KEYWORD AND TRAGET FILE NAME
findAndReplace "XXX" "demo-${BUILD_NUMBER}" "demo.txt"
findAndReplace "YYY" "yyy-${BUILD_NUMBER}" "demo.txt"