5

I tried to search the MarkDown files containing some specific text under the working directory, so I used the command below:

find . -name "*.md"  | xargs grep "interpretation"

However, though I got the result what I need, the terminal also print out much errors like below:

grep: Problem: No such file or directory
grep: Solving: No such file or directory
grep: with: No such file or directory
grep: Algorithms: No such file or directory
……
etc

I wrote my solution as a answer below.

DataAlchemist
  • 187
  • 1
  • 2
  • 11
  • 1
    if you want to search files only in current dir without going inside sub-dirs, just use `grep 'interpretation' *.md`... and if you need sub-dir as well, use `-type f` and `-exec` with `find` instead of xargs – Sundeep May 27 '17 at 14:25
  • @Sundeep ,Thank you! I have searched the usage about `-exec` and it is convenient! I will update my answer. I am a fresh man on command-line, sorry for that :) – DataAlchemist May 27 '17 at 14:44
  • using command line is never ending experience... you might want to bookmark https://unix.stackexchange.com/questions/321697/why-is-looping-over-finds-output-bad-practice if you are going to use `find` regularly – Sundeep May 27 '17 at 14:55

2 Answers2

5

Found it!

At first I used the option -s to suppress errors, suggested by here, but @Kelvin 's comment reminded me the true reason is that my many files' names has the spaces.

So the correct command is:

$ find . -name "*.md" -print0 | xargs -0 grep "some-text-want-to-find" (on os x)

Here is some clearer explanation I found:

Unix-like systems allow embedded spaces (and even newlines!) in filenames. This causes problems for programs like xargs that construct argument lists for other programs. An embedded space will be treated as a delimiter and the resulting command will interpret each space-separated word as a separate argument. To overcome this, find and xarg allow the optional use of a null character as argument separator. A null character is defined in ASCII as the character represented by the number zero (as opposed to, for example, the space character, which is defined in ASCII as the character represented by the number 32). The find command provides the action -print0, which produces null separated output, and the xargs command has the –null option, which accepts null separated input.

—— The Linux Command Line: A Complete Introduction by William E. Shotts

Warning: When you are on os x, the null separated option of xargs command is –0


Updated 2017-05-27 22:58:48

Thanks to @Sundeep ,who suggested me to use -exec, a new feature in find itself, rather than xargs.

So, use this to search files in current dir and its sub-dirs:

$ find . -type f -name "*.md" -exec grep "some-text-want-to-find" {} +

Note:

What is meaning of {} + in find's -exec command? - Unix & Linux Stack Exchange

DataAlchemist
  • 187
  • 1
  • 2
  • 11
1

I found that when there's symbolic link and the destination directory not exist, it will print out no such file or directory

吴天宇
  • 11
  • 1