linux command for finding files containing a specific word - linux

basically what is says in the title, but i mean look for files CONTAINING a word, not in the filename but in the content. Is that even possible?

The easiest way is with grep ;)
grep -r word DIR
-r is recursive
But there's also ack that is working pretty closely as grep

You can use rgrep.
rgrep pattern path
which is equivalent to
grep -r pattern path
If you only want to grep for whole words matching, you can add -w to the grep options.

I use grep for that
grep -Ri "keyword" [dir]
-R recursive
-i ignore case

Related

grep 2 words at if statements in Bash

I am trying to see if my nohup file contains the words that I am looking for. If it does, then I need to put that into tmp file.
So I am currently using:
if grep -q "Started|missing" $DIR3/$dirName/nohup.out
then
grep -E "Started|missing" "$DIR3/$dirName/nohup.out" > tmp
fi
But it never goes into the if statement even if there are words that I am looking for.
How can I fix this?
Since basic sed uses BRE, regex alternation operator is represented by \| . | matches a literal | symbol. And you don't need to touch | symbol in the grep which uses ERE.
if grep -q "Started\|missing" $DIR3/$dirName/nohup.out
You should use egrep instead of grep (Avinash Raj has explained that in other words already in his answer).
I would generally recommend using egrep as a default for everyday use (even though many expressions only contain the basic regular expression syntax). From a practical point the standard grep is only interesting for performance reasons.
Details about the advantages of grep vs. egrep can be found in that superuser question.
When you only put the grep results into the tmp-file, you do not want to grep the file twice.
You can not use
egrep "Started|missing" $DIR3/$dirName/nohup.out > tmp
since that would create an empty tmp file when nothing is found.
You can remove empty files with if [ ! -s tmp ] or use another solution:
Redirectong the grep results without grepping again can be done with
rm -f tmp 2>/dev/null
egrep "Started|missing" $DIR3/$dirName/nohup.out | while read -r strange_line; do
echo "${strange_line}" >> tmp
done

Grep command- How to use in different directories

How to grep single word in different directory and file name is also same in different directory.
I'm not sure to understand what you want.
Can't you just run
grep -rwn word /some/dir1/ /other/dir2/
Read the GNU grep documentation!
If you are using bash you can use the following:
grep 'pattern' {dir1,dir2,dir3}/filename
Specify each file as an argument:
grep -w vwhat /some/file /another/file /a/third/file

Is it possible to use "AND " and "NOT" condition in the same grep command

I need to search in a directory of files which has pattern1 but not pattern2.
look at the -v flag to grep. You can pipe multiple calls to grep together, which is probably the simplest approach here. One to look for pattern1, and another to grep -v pattern2.
grep pattern1 $(grep -L pattern2 *)
is probably the easiest way to do it, if I understand correctly what you want. -L means "print just the names of all files that do not contain this pattern"; it's the inverse of -l. This will not work correctly if you have files with whitespace or some other shell metacharacters in their names.
You can add a grep to the first grep:
grep -r "this pattern" /path | grep -v "not this patten"
HTH
Francisco

Using alias to shorten my command?

I am used to searching specific keywords under Linux.
For example, I may search "TAIWAN" under home by
grep -i -r TAIWAN ./ | grep -v".svn"
However, I thought this is a little redundant; I want to use an alias so I can type
grep TAIWAN
and then the alias will expand my command into
grep -i -r TAIWAN ./ | grep -v".svn"
How could I achieve this?
You won't be able to do it with an alias, but you can create a bash function:
mygrep () { grep -i -r $* ./ | grep -v".svn"; }
I don't believe alias can accomplish what you want because there is no way to reorder the arguments. It is simpler to make a small shell command. Rather than replace grep, and thus possibly mess up programs which expect grep to behave in a certain way, I'd give it a new name such as rgrep.
#!/bin/sh
grep -i -r "$#" | grep -v .svn
Put that somewhere in your PATH such as ~/bin and make it executable with chmod +x ~/bin/rgrep. Then you can rgrep TAIWAN ..
Unfortunately, this will ignore lines which contain .svn as well as files.
You could try to fix up the grep -v pattern match to only match the file part of the grep output, or you could whip up a more complicated command using find instead of grep -r... or you can use ack.
Ack is a better grep and will avoid version control directories and other common files and directories you don't care about. It will also automatically use a pager and color the output.

Grep Search all files in directory for string1 AND string2

How can I make use of grep in cygwin to find all files that contain BOTH words.
This is what I use to search all files in a directory recursively for one word:
grep -r "db-connect.php" .
How can I extend the above to look for files that contain both "db-connect.php" AND "version".
I tried this: grep -r "db-connect.php\|version" . but this is an OR i.e. it gets file that contain one or the other.
Thanks all for any help
grep -r db-connect.php . | grep version
If you want to grep for several strings in a file which have different lines, use the following command:
grep -rl expr1 | xargs grep -l expr2 | xargs grep -l expr3
This will give you a list of files that contain expr1, expr2, and expr3.
Note that if any of the file names in the directory contains spaces, these files will produce errors. This can be fixed by adding -0 I think to grep and xargs.
grep "db-connect.php" * | cut -d: -f1 | xargs grep "version"
I didn't try it in recursive mode but it should be the same.
To and together multiple searches, use multiple lookahead assertions, one per thing looked for apart from the last one:
instead of writing
grep -P A * | grep B
you write
grep -P '(?=.*A)B' *
grep -Pr '(?=.*db-connect\.php)version' .
Don’t write
grep -P 'A.*B|B.*A' *
because that fails on overlaps, whereas the (?=…)(?=…) technique does not.
You can also add in NOT operators as well. To search for lines that don’t match X, you normally of course use -v on the command line. But you can’t do that if it is part of a larger pattern. When it is, you add (?=(?!X).)*$) to the pattern to exclude anything with X in it.
So imagine you want to match lines with all three of A, B, and then either of C or D, but which don’t have X or Y in them. All you need is this:
grep -P '(?=^.*A)(?=^.*B)(?=^(?:(?!X).)*$)(?=^(?:(?!Y).)*$)C|D' *
In some shells and in some settings. you’ll have to escape the ! if it’s your history-substitution character.
There, isn’t that pretty cool?
In my cygwin the given answers didn't work, but the following did:
grep -l firststring `grep -r -l secondstring . `
Do you mean "string1" and "string2" on the same line?
grep 'string1.*string2'
On the same line but in indeterminate order?
grep '(string1.*string2)|(string2.*string1)'
Or both strings must appear in the file anywhere?
grep -e string1 -e string2
The uses PCRE (Perl-Compatible Regular Expressions) with multiline matching and returns the filenames of files that contain both strings (AND rather than OR).
grep -Plr '(?m)db-connect\.php(.*\n)*version|version(.*\n)*db-connect\.php' .
Why to stick to only grep:
perl -lne 'print if(/db-connect.php/&/version/)' *

Resources