如何测试变量的值是否与全局模式的值匹配

问题描述 投票:0回答:1

我正在编写一个 Bash 脚本,用于检查两个 git 提交之间的差异,并将其与 glob 模式列表交叉引用,以查看与这些 glob 模式匹配的任何内容是否已更改。

我遇到了这样的限制:只有在按字面定义 glob 时才匹配 glob,而不是从变量读取 glob。

这是我到目前为止所拥有的:

function files_changed() {
  local latter_commit=$1
  local former_commit=$2
  local files=("${@:3}")


  for file in $(git diff --name-only "$former_commit" "$latter_commit"); do
    echo "Checking file $file"
        for pattern in "${files[@]}"; do
            if [[ "$file" == $pattern ]]; then
                echo "File $file changed, matched by pattern $pattern"
                return 0
            else
        echo "File $file did not match pattern $pattern"
      fi
        done
    done

    echo "No files changed"
    return 1
}

但这不起作用:

array=("migrations/*.up.sql")
files_changed HEAD HEAD~1 ${array[@]}

输出:

Checking file migrations/20240000000001_migration.up.sql
File migrations/20240000000001_migration.up.sql did not match pattern migrations/*.up.sql

如果我从字面上比较字符串,我确实看到了我想要的行为:

> if [[ "migrations/20240000000001_migration.up.sql" == migrations/*.up.sql ]]; then echo "Match"; else echo "No Match"; fi 
Match

但如果我将它们分配给变量则不会:

> X=migrations/20240000000001_migration.up.sql; Y=migrations/*.up.sql; if [[ "$X" == $Y ]]; then echo "Match"; else echo "No Match"; fi
No Match

我可以在网上找到的解决方法都取决于扩展全局模式,但这不适合我的用例,因为与更改列表匹配的文件可能不存在于我当前的文件系统中。

如何才能正确评估此比较?

bash git glob
1个回答
0
投票

正如 @LeGEC 指出的那样,git diff 允许通过 glob 进行过滤:

function files_changed() {
    local latter_commit=$1
    local former_commit=$2
    local -a patterns=$3

    for file in $(git diff --name-only "$former_commit" "$latter_commit" -- "${patterns[@]}"); do
        echo "File $file changed, matched by patterns ${patterns[*]}"
    return 0
    done

    echo "No files changed"
    return 1
}

至于我看到的奇怪行为,那只是因为我从一个包含 bash shebang 的文件复制到运行 zsh 的 shell 中。

© www.soinside.com 2019 - 2024. All rights reserved.