我有一个 bash 脚本,它使用 grep 筛选出具有某些扩展名和某些目录下的文件。该脚本如下所示:
generate_exclud_extensions() {
echo "\"(cpp$"
}
generate_exclude_dirs() {
echo "|^test)\""
}
command=$(generate_exclud_extensions)$(generate_exclude_dir)
echo $command
git ls-files | grep -vE $command
该脚本应该筛选带有cpp
扩展名的文件以及test
目录下的文件。但结果只筛选掉了第一个,剩下了第二个。
事实 1:echo $command
输出"(cpp$|^test)"
,并在终端中运行完整命令git ls-files | grep -vE ""(cpp$|^test)""
,我得到了正确的结果。
事实 2:尝试使用 grep 两次,如下所示:
git ls-files | grep -vE "cpp$" | grep -vE "^test"
bash 脚本中出现同样的错误结果,但在终端中正确。
我一直在寻找,但还没有运气。如果有人能阐明这一点,我将不胜感激。
答案1
我设法重现了这个问题。这是两个函数中的 bash 转义问题。尝试这个:
generate_exclude_extensions() {
echo '(cpp$'
}
generate_exclude_dirs() {
echo '|^test)'
}
command=$(generate_exclude_extensions)$(generate_exclude_dirs)
echo "$command"
git ls-files | grep -vEe "$command"
我要重现的代码
generate_exclude_extensions() {
echo '(cpp$'
}
generate_exclude_dirs() {
echo '|^test)'
}
command=$(generate_exclude_extensions)$(generate_exclude_dirs)
echo "$command"
echo -e 'cpp\n
test\n
test456\n
display?5\n' | grep -vEe "$command"
您的脚本中还有两个错别字
generate_exclude_dir -> generate_exclude_dirs
generate_exclud_extensions -> generate_exclude_extensions
:) 玩得开心
答案2
另一种方法可能是:
generate_exclude_extensions() {
echo 'cpp$'
}
generate_exclude_dirs() {
echo '^test'
}
exclusions=$(
generate_exclude_extensions
generate_exclude_dir
)
printf '%s\n' "$exclusions"
git ls-files | grep -ve "$exclusions"
也就是说,每行有一个排除项,然后您甚至不需要-E
.
答案3
你可以使用 Gitexclude
路径规范过滤输出:
exclude_extensions=( '*cpp' '*.txt' ) # added `*.txt` as sample file extension
exclude_dirs=( 'test/*' ) # exclude files in relative directory `test`
git ls-files "${exclude_extensions[@]/#/:(exclude)}" "${exclude_dirs[@]/#/:(exclude)}"
参数扩展扩展"${exclude_...[@]/#/:(exclude)}"
为以空格分隔的数组条目,前缀为:(
,路径规范“魔术词”exclude
后跟)
。
结果命令相当于
git ls-files ':(exclude)*cpp' ':(exclude)*.txt' ':(exclude)test/*'