Score:-1

What's wrong with 'grep' command in Ubuntu-18.04.6?

ru flag

I enjoyed 'grep' for decades but I left Linux years later and I came back again, finding 'grep' works different from before. I checked its usage from web and confirm my memory is not corrupted.

I am sure that some *.h and *.cpp files are under deeper subdirectories. I used below commands and got unexpected similar:

grep 44738 -r -l *.h
grep 44738 -r -l *.c
grep 44738 -r -l *.c*

I got result of

 grep: *.h: No such file or directory
 ./daemons/snmpcd/snmpcd.cpp
 ./.svn/pris.......svn-base

 grep: *.c: No such file or directory
 ./daemons/snmpcd/snmpcd.cpp
 ./.svn/pris.......svn-base

 grep: *.c*: No such file or directory
 ./daemons/snmpcd/snmpcd.cpp
 ./.svn/pris........svn-base

respectively.

  • If I used command: grep 44738 -r -l ., I got the same result except the first line of grep: ...
  • If I used command: grep 44738 -r -l *.c*, I just got grep: ... without any files.
  • If I used command: grep 44738 -r -l -file *.c* ., I just got grep: *.c*: No such file or directory

The result is almost against my experience several years ago. My questions are:

  1. Did ubuntu-18.04.6 have lots of change on grep?
  2. How can I specify file patterns in grep? Why can't I used patterns like *.c, *.h *.c* as I did it years before?
  3. My coworker suggest me to use ack, but I found almost the same thing. What commands should I use for global string search like grep before?
Raffa avatar
jp flag
`*` expands only to none-hidden files and directories in the current working directory ... It doesn't include sub-directories contents ... Unless `shopt -s globstar` is set.
Jad avatar
br flag
Jad
I don't believe that grep has changed in any significant way over the years (20+ in my case) ... the use of `*.h` will be processed by the shell, not by grep, and you'd be much better off using `find` to search through directories: `find . \( -name '*.h' -o -name '*.c' -o -name '*.cpp' \) -exec grep -l 44738 {} \;`
muru avatar
us flag
If there are no `.c` files, then `*.c` will not be expanded and remain `*.c` in bash by default (the default behaviour going back two decades or so). This can be controlled by `shopt -s nullglob`, where `*.c` will expand to nothing, but then `grep foo *.c` will simply hang waiting for input as no filenames were provided (also a behaviour going back decades). I suggest you simply re-examine your memory.
Score:1
cn flag

There are two issues here. First, you cannot combine the -r or -R flags and also give target file names as arguments. The -r/-R turn on recursive search which means "search through all files in the given directories" so they will make grep treat its argument as a directory to look for files in. Since there is no directory whose name matches the *.c* glob, you get the error you show. As far as I can remember, this has always been the case, at least since I've been using Linux which has been close to 25 years now.

You can use globs as you want if you don't use the -r/-R flags, but you must quote them, this is essential. If you don't quote it, as you did, the glob will be expanded by the shell to any matching files and grep won't see the glob but only the result of the shell's expansion of it, so only any files or directories in the current directory whose names match the glob.

Now, GNU grep, the default on Linux, has a way to do what you want, but the syntax is different:

grep 44738 -r -l --include='*.h'

See man grep:

  --include=GLOB
          Search only files whose base name matches GLOB (using  wildcard
          matching  as  described  under  --exclude).   If  contradictory
          --include and --exclude options are given,  the  last  matching
          one  wins.   If no --include or --exclude options match, a file
          is included unless the first such option is --include.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.