首页 > 解决方案 > git grep 和 OR'd 多个带有管道的子句?

问题描述

我想用 grep 搜索多个子句 - 我知道可以使用管道|来 OR 子句;所以这是我在 MSYS2、Windows 10 上尝试的测试:

$ uname -s
MSYS_NT-10.0-18363
$ git --version
git version 2.25.2
$ grep --version | head -1
grep (GNU grep) 3.0

$ git clone https://github.com/xythobuz/avrSerial.git
...
$ cd avrSerial/

$ grep -r 'SERIALDATA\|UART_INTERRUPT_MASK' . --include='*.[ch]'
./serial.c:#define SERIALDATA  0
./serial.c:    rxBuffer[uart][rxWrite[uart]] = *serialRegisters[uart][SERIALDATA];
./serial.c:        *serialRegisters[uart][SERIALDATA] = sendThisNext[uart];
./serial.c:            *serialRegisters[uart][SERIALDATA] = txBuffer[uart][txRead[uart]];
./serial.c:            serialRegisters[uart]->CTRLA &= ~(UART_INTERRUPT_MASK << 2); // TXCINTLVL
./serial_device.h:#define UART_INTERRUPT_MASK 0x03

所以,在grep这里工作得很好,有多个带有管道的子句。

但是,我想知道子句/关键字匹配发生在哪些 C 函数中,所以我尝试git grep-pswitch 一起使用:

$ git grep -p 'SERIALDATA\|UART_INTERRUPT_MASK' -- '*.[ch]'
$

...对于同一个子句,绝对不会返回任何内容。

但是,如果我在 Ubuntu 上重复这个测试:

$ echo `uname -s` `cat /etc/issue | head -1`
Linux Ubuntu 18.04.4 LTS \n \l
$ git --version
git version 2.17.1
$ grep --version | head -1
grep (GNU grep) 3.1

# same procedure with git clone, cd ... grep -r works the same too; but git grep -p is different:

$ git grep -p 'SERIALDATA\|UART_INTERRUPT_MASK' -- '*.[ch]'
serial.c:#define SERIALDATA  0
serial.c=static void serialReceiveInterrupt(uint8_t uart) {
serial.c:    rxBuffer[uart][rxWrite[uart]] = *serialRegisters[uart][SERIALDATA];
serial.c=static void serialTransmitInterrupt(uint8_t uart) {
serial.c:        *serialRegisters[uart][SERIALDATA] = sendThisNext[uart];
serial.c:            *serialRegisters[uart][SERIALDATA] = txBuffer[uart][txRead[uart]];
serial.c:            serialRegisters[uart]->CTRLA &= ~(UART_INTERRUPT_MASK << 2); // TXCINTLVL
serial_device.h=uint8_t const serialBits[UART_COUNT][UART_BITS] = {{
serial_device.h:#define UART_INTERRUPT_MASK 0x03

......在这里有效?!

有谁知道为什么git grep在这些系统上会有不同的行为?是否有我必须启用的 git config 设置,或者它是回归git,或者 MSYS2 上可能存在一些 shell 转义问题?

或者一般来说 - 我怎样才能git grep在 MSYS2 上获得与在 Ubuntu 上获得相同类型的响应?

标签: linuxbashgitgrepmsys2

解决方案


我会将此作为答案发布 - 在查看git help grep并强制执行一些开关后,发现这适用于 MSYS2:

$ git grep -p --extended-regexp 'UART_INTERRUPT_MASK|SERIALDATA' -- '*.[ch]'
serial.c:#define SERIALDATA  0
serial.c=static void serialReceiveInterrupt(uint8_t uart) {
serial.c:    rxBuffer[uart][rxWrite[uart]] = *serialRegisters[uart][SERIALDATA];
serial.c=static void serialTransmitInterrupt(uint8_t uart) {
serial.c:        *serialRegisters[uart][SERIALDATA] = sendThisNext[uart];
serial.c:            *serialRegisters[uart][SERIALDATA] = txBuffer[uart][txRead[uart]];
serial.c:            serialRegisters[uart]->CTRLA &= ~(UART_INTERRUPT_MASK << 2); // TXCINTLVL
serial_device.h=uint8_t const serialBits[UART_COUNT][UART_BITS] = {{
serial_device.h:#define UART_INTERRUPT_MASK 0x03

还有这个:

$ git grep -p --perl-regexp 'UART_INTERRUPT_MASK|SERIALDATA' -- '*.[ch]'
serial.c:#define SERIALDATA  0
serial.c=static void serialReceiveInterrupt(uint8_t uart) {
serial.c:    rxBuffer[uart][rxWrite[uart]] = *serialRegisters[uart][SERIALDATA];
serial.c=static void serialTransmitInterrupt(uint8_t uart) {
serial.c:        *serialRegisters[uart][SERIALDATA] = sendThisNext[uart];
serial.c:            *serialRegisters[uart][SERIALDATA] = txBuffer[uart][txRead[uart]];
serial.c:            serialRegisters[uart]->CTRLA &= ~(UART_INTERRUPT_MASK << 2); // TXCINTLVL
serial_device.h=uint8_t const serialBits[UART_COUNT][UART_BITS] = {{
serial_device.h:#define UART_INTERRUPT_MASK 0x03

因此,请使用--perl-regexpor --extended-regexp- 并且不要|使用反斜杠转义管道\,因为通常需要这样做grep


推荐阅读