Im trying to look for the text Elapsed time
inside a specific log file names vsim.log
. Im not familiar with grep, but after some googling I found that grep -r
will allow me to do recursively searches and grep -r "Elapsed time"
will do recursive searches for that phrase within all files in my directory. According to this link, I can then do grep -r "Elapsed time" ./vsim*
to recursively search through the directories for files starting with vsim
and look inside those files for Elapsed time
. However, when i tried this i get grep: No match.
which i know is not true since I know the files exist there with those keywords. What am i messing up?
3 Answers
Continuing from my comment, you can use find
to locate the file vsim.log
if you do not know its exact location and then use the -execdir
option to find
to grep
the file for the term Elapsed time
, e.g.
find path -type f -name "vsim.log" -execdir grep -H 'Elapsed time' '{}' +
That will return the filename along with the matched text which you can simply parse to isolate the filename if desired. You can process all files that match if you anticipate more than one by feeding the results of the find
command into a while read -r
loop, e.g.
while read -r match; do
# process "$match" as desired
echo "Term 'Elapsed time' found in file ${match%:*}"
done < <(find path -type f -name "vsim.log" -execdir grep -H 'Elapsed time' '{}' +)
Where:
find
is the swiss-army knife for finding files on your systempath
can be any relative or absolute path to search (e.g.$HOME
or/home/dorojevets
) to search all files in your home directorythe option
-type f
tells find to only locate files (seeman find
for link handling)the option
-name "foo"
tell find to only locate files namedfoo
(wildcards allowed)the
-exec
and-execdir
options allow you to execute the command that follows on each file (represented by'{}'
)the
grep -H 'Elapsed time' '{}'
being the command to execute on each filenamethe
+
being what tellsfind
it has reached the end of the command (\;
used with-exec
)finally, the
${match%:*}
parameter expansion on the variable$match
is used to parse thefilename
fromfilename:Elapsed time
returned bygrep -H
(the%:*
simply being used to trim everything to the first:
from the right of$match
)
Give that a try and compare the execution time to a recursive grep
of the file tree. What you may be missing in this discussion, is that you use find
if you know some part of the filename (or file mod time, or set of permissions, etc) that contains the information you need. It can search millions of files in a file tree vastly quicker than you can recursively grep
every single file. If you have no clue what file may contain the needed info -- then use grep
and just wait...
-
Would this be in a file i execute or do i type the entire thing into the terminal ? Commented Jul 6, 2017 at 17:47
-
You can just type it into your terminal or include it in a script. Bash is wonderfully flexible. Anything you can do on the command line, you can put in a script and vice-versa... If used in a script, include
#!/bin/bash
as the first line to tell the interpreter to usebash
and not some other shell. I updated thewhile
loop to spit out the full path of the file containing any match ofElapsed time
as an example. Commented Jul 6, 2017 at 17:48 -
I also removed
tmp
which is just the directory name I used to confirm the behavior. It is actually where you tellfind
to start searching, e.g.find /path/to/search
(it will recursively search everything below that). It can be a relative or absolute path. If you runfind
on the entire root filesystem, include-mount
option to prevent searching the/dev
,/proc
, and/sys
system directories that can contain many things that are not files. Commented Jul 6, 2017 at 17:56 -
@dorojevets don't get me wrong,
find
can be a bit intimidating to make friends with. (especially when you are just starting) But, it is one of those tools that is essential enough to everything you do on a Linux system, that you are well served to go ahead and learn it now. A good general reference is Advanced Bash-Scripting Guide. It too should be your friend. Then use BashGuide - Greg's Wiki to refine your use of bash. Commented Jul 6, 2017 at 18:02
Try:
grep -r "Elapsed time" * --include vsim.log
Or this answer Use grep --exclude/--include syntax to not grep through certain files.
-
1I would prefer
.
over*
here (no chance of "command line too long", no chance of matching things that look like options to grep, no inconsistent skipping of hidden files on the top level only) Commented Jul 6, 2017 at 18:18
The following works just in case if you are using Mac:
To search UUID in *.c files recursively under given folder "/home" use the following:
grep -r "UUID" --include "*.c" /home/
To recursively search UUID in all main.c files in multiple projects under current folder use the following:
grep -r "UUID" --include "main.c" .
find /path/to/search -type f -name "vsim.log"
to then search a single or a few files. It will be much faster.*
is not interpreted by grep but by bash. It performs path expansion. This is in turn passed to grep. Likely, nothing expanded in that directory is a directory so there's nothing for grep to recurse into. As one commenter said to an answer, prefer to use.
instead of*
.