11

I want to redirect the output of the find command to cat command so I can print the data of the given file.

So for example if the output of find is /aFile/readme then the cat should be interpreted as cat ./aFile/readme. How can I do that instantly ?

Do I have to use pipes ?

I tried versions of this :

cat | find ./inhere -size 1033c 2> /dev/null

But I guess this is completely wrong? Of course I'm sure that the output is only one file and not multiple files.

So how can I do that ? I've searched on Google and couldn't find a solution, probably because I didn't search right :P

18

You can do this with find alone using the -exec action:

find /location -size 1033c -exec cat {} +

{} will be expanded to the files found and + will enable us to read as many arguments as possible per invocation of cat, as cat can take multiple arguments.

If your find does not have the + extension or you want to read the files one by one:

find /location -size 1033c -exec cat {} \;

If you want to use any options of cat, do:

find /location -size 1033c -exec cat -n {} +
find /location -size 1033c -exec cat -n {} \;

Here I am using the -n option to get the line numbers.

  • So, If I'm correct : {} is like a variable that in it is stored the output of the find command and after the "+" sign you're supposed to write the cat parameters ? No ? Edit : Alright you edited your post and now you just answered my question :P Thanx man ! Solved ! – Eksapsy Jun 26 '16 at 19:35
  • @general656 Check my edits.. – heemayl Jun 26 '16 at 19:37
0

Command Substitution

Another option is to use Command Substitution. Wrapping a command in $() will run the command and replace the command with its output.

cat $(find ./inhere -size 1033c 2> /dev/null)

will become

cat ./inhere/file1 .inhere/file3

This is more or less equivalent to using the older style of wrapping commands with back ticks:

cat `find ./inhere -size 1033c 2> /dev/null`

More details from the docs linked above

Bash performs the expansion by executing command in a subshell environment and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting. The command substitution $(cat file) can be replaced by the equivalent but faster $(< file).

When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by $, `, or \. The first backquote not preceded by a backslash terminates the command substitution. When using the $(command) form, all characters between the parentheses make up the command; none are treated specially.

Command substitutions may be nested. To nest when using the backquoted form, escape the inner backquotes with backslashes.

If the substitution appears within double quotes, word splitting and filename expansion are not performed on the results.

See this other answer for some good examples of usage.

  • Note that if find finds too many files, this would generate an "argument list too long" error whet trying to invoke cat. It would also have problems handling filenames containing whitespace characters and possibly also filenames containing filename globbing characters. – Kusalananda 19 hours ago
-1

This will print the name and contents of text (ascii) files-only recursively..

find . -type f -exec grep -Iq . {} \; -print | xargs awk 'FNR==1{print FILENAME ":" $0; }'

One more attempt

find . -type f -exec grep -Iq . {} \; -printf "\n%p:" -exec cat {} \;
-2

Use pipe and xargs

find /* -name pg_hba.conf | xargs cat

If it fails because of lack of permissions, you can use sudo to make sure you have permission to execute find command on the directory you are searching.

 sudo find /* -name pg_hba.conf | xargs sudo cat
  • 1
    And if someone has created a file called /tmp/ /dev/urandom /pg_hba.conf, that will let root dump the whole content of /dev/urandom. Worse can probably be done depending on the context. xargs should almost never be used without -0 if at all. Also sudo xargs would be better than xargs sudo. And /* would be better as /. – Stéphane Chazelas Jan 27 '17 at 0:32
  • 1
    The OP wants to use cat to print the file content on stdout. So the purpose is served by cat. The question is how to use cat from the out put of find command to print the content of the file not how to use sudo or find , The above command solves the question. Yes xargs -0 was the only constructive thing you pointed. But did not show the usage. Try not to be rude. – App Work Jan 27 '17 at 1:05
  • Sorry if that appeared rude. That was not the intention. I wanted to point out the limitations. Your answer shows bad practices (find|xargs without -0 should really be banned), hence the down vote. The output of find without -print0 is not post-processable reliably. -print0 is not standard. Having said that, standard sudo find / -name pg_hba.conf -exec cat {} + could also make you dump the content of /dev/urandom (for instance if someone created a symlink from /tmp/pg_hba.conf to it and there's no easy portable way around that that doesn't at least have a race condition). – Stéphane Chazelas Jan 27 '17 at 9:53
  • 1
    Let's not use sudo "just in case", shall we? – lindhe Jul 19 '17 at 21:41
  • Well, it's better than running sudo rm -rf / – devinbost Jan 17 '18 at 0:59

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.