1

I want to grep only header files in source code. And seems that it is well-known and already solved problem, but --include= doesn't work for me:

$ grep -rnI --include=\*.h 'static volatile'
net/ipv4/ipconfig.c:174:static volatile int ic_got_reply __initdata;    /* Proto(s) that replied */
drivers/mtd/maps/sbc_gxx.c:83:static volatile int page_in_window = -1; // Current page in window.
drivers/parport/parport_mfc3.c:79:static volatile int dummy; /* for trigger readds */
^C

I expect that there will be only header files with .h extension.
By the way, --exclude= works fine:

$ grep -rnI --exclude=\*.c 'static volatile'
arch/mips/include/asm/mach-pmcs-msp71xx/msp_gpio_macros.h:63:static volatile u32 * const MSP_GPIO_DATA_REGISTER[] = {
arch/mips/include/asm/mach-pmcs-msp71xx/msp_gpio_macros.h:83:static volatile u32 * const MSP_GPIO_MODE_REGISTER[] = {
arch/arm/mach-w90x900/include/mach/uncompress.h:28:static volatile u32 * const uart_base = (u32 *)UART0_PA;
arch/arm/mach-gemini/include/mach/uncompress.h:19:static volatile unsigned long * const UART = (unsigned long *)GEMINI_UART_BASE;
^C

UPD:

$ grep --version
grep (GNU grep) 2.27
...

$ type grep
grep is aliased to `grep --color --exclude=tags --exclude-dir="build*"'

But it works well when alias is cancelled such way: $ \grep -rnI --include=\*.h 'static volatile'.
So why does --exclude= cancels --include=?

oguz ismail
  • 1
  • 16
  • 47
  • 69
NK-cell
  • 1,145
  • 6
  • 19
  • Please post the version of grep used, GNU or other – Inian Jun 05 '20 at 09:43
  • 2
    Also see if you have an alias defined for `grep`. Post the output of `type grep`. Because I can't seem to reproduce your problem – Inian Jun 05 '20 at 09:45
  • @Sundeep I did it just in Linux kernel sources directory on my Linux machine – NK-cell Jun 05 '20 at 09:46
  • @Inian grep is aliased to `grep --color --exclude=tags --exclude-dir="build*"' – NK-cell Jun 05 '20 at 09:47
  • 2
    what happens if you use `\grep -rnI --include=\*.h 'static volatile'` (note the \ at the beginning) – Sundeep Jun 05 '20 at 09:51
  • @Sundeep It works fine! What does it mean? It cancels alias? – NK-cell Jun 05 '20 at 09:53
  • okay, exclude=tags means `skip files and directories matching tags` which will mean files not named `tags` will now be in output.. for a better example, `exclude='*.c'` means exclude files ending in `.c` which means all other files will be matched.. so it is not canceling include.. just one of the rules to filter – Sundeep Jun 05 '20 at 09:58
  • @Sundeep You can post answer :) – NK-cell Jun 05 '20 at 10:16

2 Answers2

5

For alias overriding, see: how can I override alias set in .bash_aliases

I couldn't find documentation relating to how multiple include/exclude rules affect the final list of files chosen for matching. But I think it is safe to assume that in case of conflict, the rule defined latest in the command line wins.

  • --exclude=tags will ignore any file or directory whose name is exactly tags
  • --include='*.h' will allow any file ending with .h to be matched

In this case, there is no conflict between the two rules. The first one allows grep to choose any file not named tags. The second one tells grep to allow any file ending with .h


In case of a conflict like --exclude='*foo.txt' --include='*.txt' the include rule will override the exclude rule and a file ending with foo.txt will be considered for matching

Sundeep
  • 23,246
  • 2
  • 28
  • 103
0

If you just use find to find files and grep to g/re/p within files (there are subtle clues in the names of the tools as to their purpose!) then you won't have to deal with the confusing, muddy, complexity the GNU guys created when they gave grep options to find files.

find . -type f -name '*.h' -exec grep -nIH 'static volatile' {} +

is probably all you need.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185