在shell中使用grep -q one-liners

Eli*_*gem 0 bash shell grep

我编写了一个脚本来列出包含特定文件的仓库中的提交.它工作得很好,但我不明白为什么我要写这个:

for c in $(git rev-list "$rev_list"); do
    git ls-tree --name-only -r "$c" | grep -q "$file"
    if [ $? -eq 0 ]; then
        echo "Saw $file in $c"
    fi
done
Run Code Online (Sandbox Code Playgroud)

而我通常写这样的事情:

[[ $(git ls-tree --name-only -r "$c" | grep -q "$file") ]] && echo "Saw $file in $c"
# or
[[ ! $(git ls-tree --name-only -r "$c" | grep -q "$file") ]] || echo "Saw $file in $c"
Run Code Online (Sandbox Code Playgroud)

两个短版本都不起作用:它们不输出任何内容.当我写它以显示所有不包含该文件的提交时,我得到输出:

[[ $(git ls-tree --name-only -r "$c" | grep -q "$file") ]] || echo "Did not see $file in $c"
Run Code Online (Sandbox Code Playgroud)

但是,如果我然后从输出中获取提交哈希并运行

git ls-tree -r <the hash> | grep file
Run Code Online (Sandbox Code Playgroud)

我注意到,该文件在树作了一次提交,导致我相信这是刚刚上市的所有提交的脚本程序.无论哪种方式,我可能会遗漏一些东西,但我无法弄清楚它是什么

l0b*_*0b0 6

您不需要在条件语句([[ $(command) ]])中包装命令.事实上,这将无法使用grep -q,因为您实际上正在测试命令是否打印任何内容.你可以这样做:

git ls-tree --name-only -r "$c" | grep -q "$file" && echo "Saw $file in $c"
Run Code Online (Sandbox Code Playgroud)

一般来说,任何代码块都喜欢

foreground_command
if [ $? -eq 0 ]
then
    bar
fi
Run Code Online (Sandbox Code Playgroud)

可以替换为任何一个

if foreground_command
then
    bar
fi
Run Code Online (Sandbox Code Playgroud)

甚至

foreground_command && bar
Run Code Online (Sandbox Code Playgroud)

你应该使用三个选择取决于是否foreground_command,bar或两者都是多行命令.