- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在主存储库中有两个子模块,它们与主存储库中的代码紧密耦合。如此之多,以至于在执行 git grep 时,我希望将主仓库与这两个特定的子模块一起进行 grep。我不能为每个“git grep ... || true”做一个完整的 git 子模块,因为我还有其他非常大的子模块,并且 grep 遍历这些子模块每个子模块可能需要 15-20 秒。
因此,我需要一个比 git submodule foreach 更具体的解决方案,它允许我指定要 grep 的特定子模块,以及 grep 我的主仓库。
我的两个子模块是 foo
和 submodules/bar
这是我目前的解决方案。这让我可以说 git gpx -i something.*interesting
等。我在创建 git 别名方面还是个新手,所以我希望这个解决方案可以得到改进。
[alias]
inr = "!f() { cd $1 && $2 ;}; f"
gprs = "!f() { for r in $1; do git inr $r \"git grep $2\" | perl -pe \"s|^|$r/|\"; done ;}; f"
gpx = "!f() { git grep $*; git gprs 'foo submodules/bar' \"$*\" ;}; f"
编辑:我发现的一个问题是我丢失了正则表达式周围的引号,所以我不能这样调用:git gpx -i "foo bar"
,因为它被翻译成这样:git grep -i foo bar
。我想不出一个干净的方法来避免这种情况。
最佳答案
重做:我用那个脚本编写了一个 bash 脚本来执行分页(在底部提到),但注意到您的示例已经在搜索路径前添加了前缀。我稍微修改了您的别名,现在发现这对我有用:
[alias]
gpx = "!f() { list=$1; shift; for r in . $list; do ( cd $r; git grep $@ | perl -pe \"s|^|$r/|\"; ); done ;}; f"
如果您使用子 shell,那么您可以折叠“inr”功能“( cd $1; cmd; ... )”(因为它隔离了 chdir),如果您添加一个“.”然后它也会搜索 super 模块。我用类似的东西测试了它
git --no-pager gpx 'foo submodules/bar' --color=always -nIE '\w+\(\w*\)' | less -R
它似乎很适合转义(打算使用 git-rev-parse --sq-quote
但似乎 git 已经为你处理了)。这似乎比下面列出的脚本内容更优雅,也许我可以使用带有函数前缀的别名样式并替换/简化许多该功能。话虽如此,感谢您展示这一点!
试图为传呼机的东西使用 gpx
创建另一个别名,但是转义有点麻烦,所以我也创建了另一个别名:
[alias]
gpxp = "!f() { list=$1; shift; for r in . $list; do ( cd $r; git --no-pager grep --color=always $@ | perl -pe \"s|^|$r/|\"; ); done | less -R ;}; f"
然后就变成了
git gpxp 'foo submodules/bar' -nIE '\w+\(\w*\)'
注意:如果出现错误,这些错误将显示在 grep 文本结果中。
原创:
我遇到了 similar problems转义和使用 git 别名。
我一直在为 git-submodule
编写一个小扩展,它允许您进行约束迭代。该功能的帮助在 git-submodule-ext foreach [-c | --constrain]
(help,implementation)。安装说明在这里:README
如果您希望将迭代限制为foo
和something/bar
,您可以在 super 模块中执行
git config scm.focusGroup 'foo something/bar'
然后做你的greppage
git --no-pager submodule-ext foreach -t -r -c -k git grep 'expression'
或者如果你使用别名安装,
git --no-pager tsfer -c -k git grep 'expression'
git --no-pager
选项是为了防止每个子模块在每次搜索后 pull 起 $GIT_PAGER
。我向脚本添加了一个 --keep-going
选项,这样如果 grep 没有返回任何内容(导致非零状态),它不会停止迭代。另一种解决方案是使用 git tsfer -c -k 'git grep "expression"|| 在子模块文档中执行示例:'
,它们等效地工作。
如果您的表达式很复杂,例如查找函数调用 '\w+\(\w*\)'
,您需要将整个表达式括在双引号中:
git --no-pager tsferp -c -k "git grep -E '\w+\(\w*\)'"
如果转义是一个大问题并且您使用的是 bash,则导出一个函数以在迭代中使用(我修改的扩展脚本使用的是 bash
,而不是 Git 的标准 /bin/sh
)
greppage() {
git grep -E 'some(really)?complex.*\(expression\)'
}
export -f greppage
git --no-pager tsfer -c -k greppage
希望对您有所帮助。
注意:目前的一个缺点是可能很难找出匹配项位于哪个子模块。可以通过某种方式在子模块的 $name
前面添加修复,但是我查看了 git grep
的选项,但找不到类似的东西。我稍微修改了命令并想出了这个,呃,'紧凑',命令:
git --no-pager sube -q foreach -t -r -c -k "echo [ \$name ]'\n'; git grep --color=always -E '\w+\(\w*\)'; echo '\n\n'" | less -R
这会使 foreach 安静(抑制“Entering”输出),并添加一些大括号和换行符以便更容易看到子模块之间的划分。让我看看我是否可以为此创建一个函数/别名以使其更容易。
编辑:这是拼凑在一起的脚本,不是那么优雅。我只是把它变成了一个 bash 函数来简化事情
git-greps() { git --no-pager sube -q foreach -t -r -c -k "git grep --color=always $(git rev-parse --sq-quote "$@") | perl -pe \"s|^|\$name/|\"" | less -R; }
例子
git-greps -nIE '\w+\(\w*\)'
关于git grep 主要仓库和特定子模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17057901/
我有一个文件 test.log。非常大的日志文件。它有不同级别的日志记录。例如,trace , debug , info , warning和 error . 显然trace级别消息只是高速发送垃圾邮
我正在经历一些事情,发现了我无法理解的事情, grep -v grep 这意味着什么?我知道 -v 开关将选择所有不匹配的行。但为什么是第二个grep? 这是完整的命令: ps -ef | grep
我使用 egrep 输出一些带有平台名称的行: XXX | egrep "i686-nptl-linux-gnu$|i686-w64-mingw32$|x86_64-unknown-linux-gnu
grep退出状态部分报告中的手册: EXIT STATUS The exit status is 0 if selected lines are found, and 1 if not
我试图返回多个字符串的第一次出现,即,我想从以下文本中选择第一次出现 1259、3009 和 1589 的行。 ADWN 1259 11:00 B23 ADWN 3009
我猜它不是 Perl 兼容的正则表达式,因为有一种特殊的 grep具体来说就是 PCRE。什么是grep最相似? grep有什么特别的怪癖吗?我需要知道什么? (我习惯了 Perl 和 PHP 中的
有没有办法让 grep 从与搜索表达式匹配的文件中输出“单词”? 如果我想在多个文件中查找“th”的所有实例,我可以这样做: grep "th" * 但是输出会是这样的(粗体是我写的); some-t
我有许多(近 100 个)大 csv 文件,第一列中有 sellID。我知道某些 sellID 在 2 个或更多文件中重复 2 次或多次。是否可以使用 grep 找到所有重复的 sellID(创建映射
我有一个文件中的文件列表。该列表很大,并且文件名是非标准的:这意味着有些文件包含空格、非 ASCII 字符、引号、单引号... 因此,将庞大的文件列表作为参数传递给 grep 并不是一种选择: 因为我
我想在 shell 脚本中使用 grep 和两个变量 var = match cat list.txt | while read word_from_list; do grep "$word_
我有一个大文件,其中每一行都包含一个子字符串,例如 ABC123。如果我执行 grep ABC file.txt 或 grep ABC1 file.txt 我按预期返回这些行,但如果我执行 grep
当我执行以下 grep 时,我得到的结果我无法向自己解释: host:/usr/local/tomcat > grep '-XX:PermSize=256m' * RELEASE-NOTES:
这个问题在这里已经有了答案: grep recursively for a specific file type on Linux (5 个回答) 关闭4年前。 要在子目录中查找所有带有 .out 扩
有什么方法可以让我在搜索某些东西时使用 grep 忽略某些文件,相当于 svnignore 或 gitignore 的东西?我通常在搜索源代码时使用类似的东西。 grep -r something *
有没有办法让 grep 从匹配搜索表达式的文件中输出“单词”? 如果我想在多个文件中找到“th”的所有实例,我可以这样做: grep "th" * 但是输出会是这样的(粗体是我的); some-tex
我是 awk/sed 的完全菜鸟,所以如果我在这里遗漏了一些明显的东西,请原谅我。 基本上我正在尝试做一个嵌套的 grep,即类似于: grep $value `exim -Mvh $(`exim -
我正在尝试编写下载 node.js source 的脚本和 corresponding SHASUMS256.txt ,校验和,grep OK,不返回任何结果,使用 grep 的 -q 标志成功退出代
在 grep "str"* 这是否意味着 grep 执行 grep 的所有内容? 那么 grep -r "str". 的结果比前一个多 最佳答案 当您运行 grep str * 时,shell 将扩展
我正在尝试 grep 文件以查找匹配项的确切出现,但我也得到了更长的虚假匹配项: grep CAT1717O99 myfile.txt -F -w 输出: CAT1717O99 CAT1717O99
我有一个文件,其中包含我希望通过未指定分析运行的标识符(每行一个)。如果一切运行正常,分析将输出具有相同标识符的另一个列表(不一定按相同顺序)。 然而,事实证明,对某些输入标识符没有进行分析,并且这些
我是一名优秀的程序员,十分优秀!