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
  • 12,914
  • 37
  • 45
  • 86
Rodolfo
  • 11
  • 1
  • 2
  • 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
  • 1,899
  • 1
  • 11
  • 26
-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
avisitoritseems
  • 306
  • 5
  • 18
  • 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