I tried to find all the lines containing word heaq
in *.md file
$ for i in $(find . -regex ".*md$"); do grep -i "heaq"; done
#pending
#pending
However, it constantly pending there.
What's the problem with my code?
I tried to find all the lines containing word heaq
in *.md file
$ for i in $(find . -regex ".*md$"); do grep -i "heaq"; done
#pending
#pending
However, it constantly pending there.
What's the problem with my code?
It is the grep
that is "pending". When grep
is run without a filename to read from, it will read standard input. If you don't provide any data on standard input, it will appear to "hang".
You are also looping over the output of find
. This is inelegant (the loop won't run until all pathnames has been found by find
) and dangerous (the pathnames will be split on whitespaces and the shell will perform filename globbing on them).
Instead, if you want to run grep
on all files with a particular filename suffix:
find . -type f -name '*.md' -exec grep -iF 'heaq' {} +
I've changed the -regex
thing to a standard -name
test with a pattern that matches only filenames with a .md
filename suffix. I've also added -type f
as it only makes sense to run grep
on regular files (you may possibly want to change -type f
to ! -type d
to run it on any non-directory instead).
The grep
is executed through -exec
in batches on the found pathnames. I'm using -F
with grep
as we are matching a string, not a regular expression. You may want to add -w
if you want to match a word rather than any substring.
Related:
you need to pass the file name to grep
so like
$ for i in $(find . -regex ".*md$"); do grep -i "heaq" $i; done
you can also use
% grep -i -n "heaq" $(find . -regex ".*md$")
-n
makes grep prints out matching line numbers
find
output in this manner is going to be fragile - better to use something like find . -regex ".*md$" -exec grep -i "heaq" {} ';'
(or find . -regex ".*md$" -exec grep -i "heaq" {} +
if supported). Also worth pointing out that -regex
is overkill here - a simple -name "*.md"
glob match should be sufficient
– steeldriver
Nov 05 '18 at 01:33
find
implementation that has the non-standard -regex
is bound to have the standard -exec ... {} +
.
– Kusalananda
Nov 05 '18 at 06:54