【问题标题】:Using grep -q in shell one-liners在 shell 单行中使用 grep -q
【发布时间】:2015-11-25 18:30:12
【问题描述】:

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

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

而我通常会这样写:

[[ $(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"

这两个短版本都不起作用:它们不输出任何东西。当我编写它以显示所有不包含该文件的提交时,我确实得到了输出:

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

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

git ls-tree -r <the hash> | grep file

我注意到文件 is 在树中用于一些提交,这让我相信它只是列出了脚本处理的所有提交。无论哪种方式,我都可能遗漏了一些东西,但我无法确切知道它是什么

【问题讨论】:

  • 试试:git ls-tree --name-only -r "$c" | grep -q "$file" &amp;&amp; echo "Saw $file in $c" || echo "nope"
  • 如果您通常写其中任何一个,那么,如 l0b0,在他们的回答中表明您一直做错了。看看那些不可能永远工作。

标签: bash shell grep


【解决方案1】:

您不需要将命令包装在条件语句中 ([[ $(command) ]])。事实上,这永远不会与grep -q 一起工作,因为您实际上是在测试该命令是否打印 任何内容。你可以这样做:

git ls-tree --name-only -r "$c" | grep -q "$file" && echo "Saw $file in $c"

一般来说,任何类似的代码块

foreground_command
if [ $? -eq 0 ]
then
    bar
fi

可以替换为任一

if foreground_command
then
    bar
fi

甚至

foreground_command && bar

您应该使用三种替代方法中的哪一种取决于foreground_commandbar 还是两者都是多行命令。

【讨论】:

  • 我不敢相信我是那么愚蠢...我基本上错过了 grep 命令中的-q。我现在可以打自己了:)
【解决方案2】:

awk 救援:

git ls-tree --name-only -r "$c" | awk "/$file/{printf '%s in %s\n', '$file', '$c'}" 

【讨论】:

    猜你喜欢
    • 2010-11-29
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多