grep
基础
用于从提交历史或者工作目录中查找一个字符串或者正则表达式。
-
grep 不能查找未跟踪的文件。
-
基本格式为
git grep <content> <sha1> file...
会输出所有包含 content 的行。-
基础格式中,可以省略 sha1 与 file。
-
不指定 sha1 值时,就在当前工作目录中进行查找。指定 sha1 值时,会在指定的版本中进行查找。
-
不指定 file 时,会查找所有文件;指定文件时,会查找指定的文件。
-
-
在基本格式的最后可以指定多个文件。
-
该命令会递归查找子文件。所以不需要额外的参数指定成递归模式。
$ git grep xx
test.html:xxx
xxx.xxx:xxxxxx 修
命令用于查找所有包含字符串 xx 的行。
如果指定了文件,则只会查找指定文件中满足条件的行。
常用选项
选项 | 含义 |
---|---|
-n | 输出匹配项所在的行 |
--count 或 -c | 输出文件中匹配的个数 |
-p | 查看匹配的行属于哪一个方法 |
--name-only | 只显示文件名 |
-i | 查找的内容不区分大小写 |
-e | 后跟正则表达式 |
-v | 显示不满足条件的行 |
基本选项
如:
$ git grep -n xx
test.html:2:xx
xxx.xxx:1:xxx
$ git grep --count xx
test.html:1
xxx.xxx:1
第一个命令表示从当前工作目录中查找含有字符串 xx 的行,并输出。
第二个命令表示输出每一个文件中能匹配字符串 xx 的次数。可以将 --count 换成 -c 。
$ git grep -p a *.java
cid.java:private void a(){}
cid.java=public void b(){
cid.java: a();
倒数第二行输出了 a() 函数的调用者为 b() 函数,虽然该行没有包含字符 a。
一般来说,使用 -p 时,需要将查找范围限定在源文件。如上例中,使用 *.java
限定只查找后缀名为 java 的文件,这样可以避免别的文件的干扰。
-v
用于显示不满足条件的行。
如:
$ cat test
Transfer your stuff from iOS in 3 easy steps.
First, download Google Drive to your iOS device and sign in with your Google account.
If you don’t have a Google account,
You can create one now or when you sign in to Google Drive.
$ git grep -v -i 'google'
test:Transfer your stuff from iOS in 3 easy steps.
test:
第一个命令用于获取当前 test 文件的内容。第二个命令用于显示不满足 google (不区分大小写情况下) 的行。
-e
-e 选项后面跟正则表达式。
注意:
- 使用时,需要将 {、} 进行转义。
如:
$ git grep -ni -e 'o\{2\}'
test:2:First, download Google Drive to your iOS device and sign in with your Google account.
test:3:If you don’t have a Google account,
test:4:You can create one now or when you sign in to Google Drive.
在不区分大小写的情况下,获取含有两个字母 o 的行。如果上述命令不对 {} 进行转义会报错。
逻辑关系
选项 | 含义 |
---|---|
--and | 与。表示表示必须满足 |
--or | 或。表示条件满足一个即可 |
--not | 否。不能满足指定的条件 |
() | 修改逻辑执行顺序。小括号内的先执行 |
默认的逻辑关系是 --or
。
使用 () 时一定要注意:需要对 ( 和 ) 进行转义,同时 ( 和 ) 与具体内容之间应通过空格隔开。
下面操作的所有文件都与 -v 时文本相同。
-
如果想获取含有 google 字样和数字的行,可以使用如下命令:
$ git grep -n -i -e 'google' --and -e '[0-9]'
可以发现,没有输出的内容。因为文本中没有满足指定条件的行。
-
如果想要获取含有 google 字样或数字的行。命令如下:
$ git grep -n -i -e 'google' -e '[0-9]' test:1:Transfer your stuff from iOS in 3 easy steps. test:2:First, download Google Drive to your iOS device and sign in with your Google account. test:3:If you don’t have a Google account, test:4:You can create one now or when you sign in to Google Drive.
在命令中第二个
-e
之前省略了--or
。因为默认的就是 or。可以发现将所有的行都输出了。因为第一行含有数字 3,其余行含有 Google,在忽略大小写的情况下可以匹配
google
。
-
如果要获取含有 google ,同时不能含有 ios 的行。命令如下:
$ git grep -n -i -e 'google' --and --not -e 'ios' test:3:If you don’t have a Google account, test:4:You can create one now or when you sign in to Google Drive.
命令中通过 --not 对表达式进行否定。因为第二行含有 ios 字样,所以不满足
--not -e 'ios'
条件,无法被输出。
-
--and 优先级高于 --or。如:
优先级
从中可以看出,所以行都满足条件。因为第一行满足 or 前面的条件,而剩余的三行满足后面的条件。
-
可以通过使用 () 使 or 先执行。如:
$ git grep -n -i -e 'ios' --and \( -e '[0-9]' --or -e 'google' \) test:1:Transfer your stuff from iOS in 3 easy steps. test:2:First, download Google Drive to your iOS device and sign in with your Google account.
上述命令查找的行必须含有字符串 ios ,同时也必须有数字或 google。因此,只有一、二行满足条件。
在写命令时,( 与 ) 都进行了转义,同时 ( 、 ) 与具体的内容 ( 即 -e '[0-9]' --or -e 'google' ) 都使用空格进行了分隔。
指定版本
grep 命令可以查询指定版本中满足条件的语句。
使用该功能可以 导出指定版本的指定文件。
如:
$ cat aa
a11
a2
a33
$ git grep -e '[\s\S]*' HEAD~ -- aa
HEAD~:aa:a11
HEAD~:aa:a2
使用的正则表达式可以匹配任何字符,因此输出时,会输出 HEAD~ 版本中 aa 文件的所有内容。