1

What I want is to find within a directory all the files containing a match and when it finds the match it shows the file where that match was found.

example

cat * | grep password: 

Here it will show me all the matches that have a "password:"

But it doesn't show which file the match belongs to.

guntbert
  • 13,134
Rodolfo
  • 11
  • 12
    Why use cat when you can grep directly? You can use grep -R "pattern" . (-R would search for pattern recursively and . refers to current directory). If there's some other reason to use cat, please [edit] your question and explain that. – Kulfy Jul 22 '20 at 19:18
  • 4
    Note that grep password * will - by default - print the names of files in which matches are found if `matches multiple files*. If you want it to print filenames unconditionally, add the-H(or long-form--with-filename`) option – steeldriver Jul 22 '20 at 20:59
  • Why not simply use the -H option? for example grep 'password:' -H -r and for filenames only use -l option (instead of -H) –  Jul 23 '20 at 07:29

2 Answers2

8

I think it's not possible to get the filenames after you piped the result of cat like in your example, because the cat command will just concatenate the contents, the information about filenames is gone after that.

What you could do instead is to rely on the grep command's behavior when it gets multiple input files, then grep will show the filename for each match.

So, instead of

cat * | grep password:

you could do this:

grep password: *
Elias
  • 2,039
-2

Using cat and grep to print out the names of files that contain the "password:" string within the current directory:

cat * 2>&- | grep -ls 'password:' *

With full file path:

cat * 2>&- | grep -ls 'password:' ${PWD}/*

2>&- is used to suppress error messages about being unable to read certain files/directories.


Using only grep to do the same thing:

grep -ls 'password:' *

With full file path:

grep -ls 'password:' ${PWD}/*


Using grep to pattern match for the "password:" string, printing the filename, then using cat to display the entire file(s) contents:

for match in $(grep -ls 'password:' *) ; do
    echo "${match}"
    cat "${match}"
done

With full file path:

for match in $(grep -ls 'password:' *) ; do
    echo -e "\e[7m\n$(readlink -f "${match}")\e[0m"
    cat "${match}"
done
  • 3
    The whole first section is at best misleading, since grep does not read from the pipe when used in this way. They're just immensely overcomplicated versions of the grep-only commands you show next. This is not, in any reasonable sense, using both cat and grep to do anything. – Eliah Kagan Jul 23 '20 at 11:15
  • Regardless of efficiency, the poster was interested in seeing cat used. – avisitoritseems Jul 24 '20 at 05:37