创建名为 demo.txt 的文件,内容如下。

创建名为 demo.txt 的文件,内容如下。

这个 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使用这里的文件语法与catcat: 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显然,这是因为)...您可以改为依赖greps 退出状态,该-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"

相关内容