I'm trying to figure out the best and fastest way of finding files whose content is specifically "something"

Here's the reason: I have a process that I'm pretty sure stores its PID somewhere in a file, but I don't know where (and I want to find out). I have tried looking for filenames that may be used for storing said pid (/var/run/myproc.pid, and so on), but without success so far. I would like to give it a try searching for files whose content is just that number. I'd like to get the PID from ps -aux or top, or some tool like that and then search for files whose content is only that number.

I've been googling around but all the answers seem to explain how to find files that contain "something"... among its contents. I want something slightly different... I want an exact match of that "something"

Thank you in advance.

  • I'd go look at the documentation for the program you are running first to make sure it does indeed do what you think it does before going on a possible wild goose chase for a magic number across /var, /run, /tmp, etc.
    – jw013
    Commented Jul 26, 2012 at 15:33
  • @jw013 Yeah, I tried that, but someone has been tweaking the code and it's not where it's supposed to be (inside the /var/run/ directory... it's somewhere else). Thanks for the hint, though.
    – Savir
    Commented Jul 26, 2012 at 15:37

6 Answers 6


Put the desired text in a file, then run cmp on every candidate file.

pgrep myproc >/tmp/the_pid
find /var -type f -size $(wc -c </tmp/the_pid)c -exec cmp -s /tmp/the_pid {} \; -print

But for this use case, I would restart the program under strace -eopen or with an auditd rule:

auditctl -F "ppid=$$,a2&0x100" -S open
  • 1
    that will spawn a lot of cmp processes that will exit once they see the file has a different size. using my answer find would do that statting and a lot less processes would be spawned Commented Jul 27, 2012 at 17:41
  • @ysangkok Good point, which I'd noticed in your answer but didn't think of when writing mine (to recommend restarting and using strace, and also suggest cmp rather than diff). Commented Jul 27, 2012 at 18:03

You can pass a Regular Expression to grep, try this: (assuming PID is 67543)

grep -R '^67543$' /

In regular expression the ^ carrot (sp) symbol means "start of string", and the $ dollar sign symbol means "end of string", so the regex above will only return result where the file starts and ends with the string "67543".

  • 1
    "only [...] where the file starts and ends". False! It will find all files with any matching line! $ grep -R "^donkey$" searchtree searchtree/test1:donkey $ od -c searchtree/test1 0000000 d o n k e y \n b i g m a n \n 0000017 Commented Jul 26, 2012 at 15:18
  • @ysangkok That's why I didn't use extended regex. You are also uselessly "catting" a file, my example did not do such things. Don't just take bits and pieces of the code and paste it into incompatible code and expect it to work.
    – Tim
    Commented Jul 26, 2012 at 15:25
  • grep matches and returns lines, not files. A recursive grep will return any file containing a line that is an exact match. I don't think that was what the question asked.
    – jw013
    Commented Jul 26, 2012 at 15:31
  • @Tim: The extended regex made no difference, I removed it. The catting was done to show you that the file had two lines even though we're searching for a file with one line. That's why I changed it to od. I'd change it more and make it prettier if the 5 min edit deadline hadn't expired. The od is not part of the solution, it is to show you that the grep gives the wrong result for this problem. Commented Jul 26, 2012 at 15:40
find searchtree -type f -size `stat -c%s needle`c | xargs -n1 diff -s needle
  • There must be something I'm doing wrong... Let's say I try to find 1234 in the files in /tmp/... If I do this: find /tmp/ -type f -size stat -c%s 1234c | xargs -n1 diff -s 1234 I get the following errors: stat: cannot stat 1234': No such file or directory find: Invalid argument c' to -size diff: missing operand after 1234' diff: Try diff --help' for more information.
    – Savir
    Commented Jul 26, 2012 at 15:20
  • you get the command as output when you execute it? impossible Commented Jul 26, 2012 at 15:21
  • try editing your question and append the errors, i think the comment box is too small Commented Jul 26, 2012 at 15:22
  • Sorry, very bad case of copy/paste. I fixed it
    – Savir
    Commented Jul 26, 2012 at 15:26
  • ah. you just need to put the pattern/needle in a file. you can do that with echo -n "thisiswhatiwanttosearchfor" > needle. remove "-n" if you want the trailing newline that you get per default in most textfiles. if your "needle" file is called "1234" of course you should use that instead of "needle". Commented Jul 26, 2012 at 15:29

if pcregrep is available in your installation, you could pass the -l (list filename), -r (recursive) and -M (multiline) flags to it to get the job done. Note that \A and \Z represent start and end of string anchors. In the example below, 12477 is the string being searched

pcregrep -l -r -M '\A12477\Z' dir

If your program isn't started at boot or together with a zillion of other programs, your pidfile should be as old as the process, which is less than one minute in the beginning.

If you know the PID, you know it's length, so you can reduce the number of files to search for even further:

 find -type f -mmin -1 -size 6c -exec grep 12345 {} \;

For a 5 digit PID use 6c as size, since they contain a trailing newline (from ysangkok as comment).

  • 1
    the PID files have trailing newlines, so you need to change the 5 Commented Jul 26, 2012 at 15:59

Something like ...

ps ax|grep ntpd|cut -b1-5|xargs -I PID find /var/run/ -type f -exec grep '-l' '^PID$' {} ';'

Note that the grep pattern specifies that the search string must be the only thing on the line, i.e. it's

string (PID is replace by value sent to `xargs`)

PS: I tested this by doing ps ax > /var/run/psaxdump followed by the above. It only found ntpd.pid

  • Mixing in a head -1 would help avoid wasting time reading in any unexpectedly huge files. If you want to be truly pedantic, even that would have false positives for files that started with the PID on a line by itself but contained other data.
    – Jander
    Commented Jul 27, 2012 at 13:53
  • grep only does line-wise comparison. As Jander has noted above, this may result in false positives since any file containing the search string will match. Gilles' approach is much more sound.
    – jw013
    Commented Jul 27, 2012 at 14:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .