Find | grep doesn't work in Cygwin

4

I have cygwin installed and when I search for the source code with this command nothing show up, even that I have that string in a file

$ echo foo > bar
$ find . -name '*' | grep foo

Nothing shows up. This command works fine on GNU+Linux.

$ grep foo bar

jcubic

Posted 2015-12-09T09:46:01.877

Reputation: 1 533

1Could also pipe find to xargs, as in $ find . | xargs grep foo – Xen2050 – 2015-12-09T10:10:29.733

@Xen2050 you can add that as an answer, I forget xargs. – jcubic – 2015-12-09T11:31:32.970

@jcubic You don't need to use find at all. See my answer. – DavidPostill – 2015-12-09T12:28:27.370

Just out of curiosity, what does $ which find return on Cygwin? – SΛLVΘ – 2015-12-13T21:19:04.903

@SalvoF /usr/bin/find – jcubic – 2015-12-14T09:11:10.393

Answers

3

As mentioned, find outputs a list of found files to stdout, grep normally expects to search through stdout if called this way.

Could also pipe find to xargs, and it will "build and execute command lines from standard input", as in

$ find . | xargs grep foo

If you have crazy filenames, with newlines and whatnot, then this would be better:

$ find . -type f -print0 | xargs -0 grep foo

and the -type f will only find regular files, so no attempts to grep through any . or .. or any directories or "funny" files.

Xen2050

Posted 2015-12-09T09:46:01.877

Reputation: 12 097

That is messy output (lines like grep: .: Is a directory and grep: ./test: Is a directory. You might consider adding --exclude-dir=* to grep. Or just use grep --exclude-dir=* "foo" ./* as per my answer ;) – DavidPostill – 2015-12-09T12:24:31.550

@DavidPostill I was going to add the -type f tag in there, I always use it in these situations, but I was sticking with the general format in the question & other answers. I'll add it in though – Xen2050 – 2015-12-09T12:51:03.177

9

find . -name  '*' # This will produce a list of *file names*

You then pass your list of filenames to grep on stdin, it treats the list as text and searches for foo

You have no file name of foo so it returns nothing.

To search recursively through files looking for text in a file you can simply use

grep -R foo somefolder/

squareborg

Posted 2015-12-09T09:46:01.877

Reputation: 2 105

find | grep work on linux – jcubic – 2015-12-09T10:13:45.110

4@jcubic if your command find . -name '*' | grep foo find the word foo inside of the files listed by the find command then your Linux is broken and you should file a bug. – squareborg – 2015-12-09T10:19:27.277

@stemartin I have a theory: A recent GNU grep + alias grep="grep -r" you get that behaviour, since GNU Coreutils developers in their great wisdom decided that grep -r on STDIN makes no sense and instead we will silently fix it to grep the current directory. I personally consider that behaviour a major bug. – oals – 2015-12-09T20:14:55.600

2

When I search for the source code with this command nothing shows up

$ echo foo > bar
$ find . -name '*' | grep foo

find searches for filenames that meet a desired criteria: Name, Size, File Type and returns a list of matching filenames. It doesn't return the contents of the matching files.

When that list of filenames is passed to grep using the pipe operator grep will see the string bar (the filename) and not foo (the contents of file bar).

grep therefore doesn't find a match so has nothing to output.

Note:

  • grep can search files directly. You don't need to use find. pipes |, or xargs as suggested in another answer.

The following command works on Cygwin:

grep --exclude-dir=* "foo" ./*

Example:

DavidPostill@Hal /f/test
$ cat bar
foo

DavidPostill@Hal /f/test
$ grep --exclude-dir=* "foo" ./*
./bar:foo

Further Reading

DavidPostill

Posted 2015-12-09T09:46:01.877

Reputation: 118 938

0

I think you want this.

find . -name '*' -type f -exec grep foo /dev/null {} \;

You only want to grep files, not directories or special files. The /dev/null makes grep show the file name. You may want to get rid of '-name '*', but if you do, then dot files will be grepped.

You could also run

grep -r foo .

Robert Jacobs

Posted 2015-12-09T09:46:01.877

Reputation: 196

Your first command is much slower than my solution of grep --exclude-dir=* "foo" ./* which produces identical output. – DavidPostill – 2015-12-09T16:33:30.567

grep -r foo . can be shortened to grep -r foo – DavidPostill – 2015-12-09T16:36:20.043

@DavidPostill Only on recent versions of GNU grep. It's braindead behaviour IMHO. – oals – 2015-12-09T20:16:37.393

@oals Oh. I didn't know that. Thanks. – DavidPostill – 2015-12-09T20:20:41.083