2

I am using grep to recursively look through files and pull out all strings matching a pattern. I want to print the file path: matched string.

-H should print the file path for each entry

-o should print just the matched string, omitting everything else on the line I don't want

-r recursive search.

I run:

grep -Hro [pattern] .

Most of the matches print with the filename, however a few just print the matched string. Are -H and -o mutually exclusive in that -o is trimming the filename? Sample Output:

./path/foo.txt: foo
./path/bar.txt: foo
./path/baz.txt: foo
foo
./path/baz.txt: foo

The 4th foo match should also have a file associated with it, but it is not being printed.

I am getting behavior similar to this post, however I am using the -H flag, and the "/dev/null" solution does not work either.

$ grep --version
grep (BSD grep) 2.5.1-FreeBSD

EDIT:

After further exploring each match where the regex was not getting the file name, they all occur when two strings are matched on the same line. For example this text file

foo
foo sometext foo
foo

Outputs

./path/foo.txt: foo
./path/foo.txt: foo
foo
./path/foo.txt: foo

Anyone know a solution to get both matches to print a filename?

  • Following your edit: To get further and maybe reproduce the behavior, you should give us the actual line that contains the two "foo", and the regexp you use. – xhienne Sep 22 '17 at 17:47
2

No, -H and -o are not mutually exclusive. You may have a Carriage Return character in the part that is matched. This would make the following text be written at the start of the line, thus overwriting the file name.

$ printf 'foobar\n' | grep -Ho '.bar'
(standard input):obar

$ printf 'foo\rbar\n' | grep -Ho '.bar'
bar

Also, since both lines belong to the same file baz.txt (if your example is correct), this may also be due to a long line (larger than the screen width) being wrapped to the next line.

$ printf 'foo%80sbar\n' | grep -Ho 'foo.*'
(standard input):foo
       bar

Whether one of those scenarios may apply to your situation really depends on your search regex and the content of your files.

  • You first example actually produces barandard input):... – Stephen Kitt Sep 21 '17 at 22:26
  • @StephenKitt Actually, that's what I was expecting but on my terminal I get what I wrote in my answer. – xhienne Sep 21 '17 at 22:36
  • I stand corrected, if your grep outputs colour you will indeed only get bar. I had tried with a non-colourised grep (which does result in barandard input):). (The curious can run printf 'foo\rbar\n' | grep -Ho --color=always '.bar' | od -xa to understand what’s going on.) – Stephen Kitt Sep 22 '17 at 4:20
  • Nice catch @Stephen, I did notice that redirecting to hexdump shows that the text was here but I wasn't able to figure out why it wasn't visible. – xhienne Sep 22 '17 at 9:56
  • Both of these are great ideas of what could have been happening given no knowledge of the regex or the text file. Exploring to see if either of these were the issue, I found what is causing it and edited my question. I still don't have a solution for the issue however. – Justin Olson Sep 22 '17 at 16:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.