Find files containing a given text
BashFindBash Problem Overview
In bash I want to return file name (and the path to the file) for every file of type .php|.html|.js
containing the case-insensitive string "document.cookie" | "setcookie"
How would I do that?
Bash Solutions
Solution 1 - Bash
egrep -ir --include=*.{php,html,js} "(document.cookie|setcookie)" .
The r
flag means to search recursively (search subdirectories). The i
flag means case insensitive.
If you just want file names add the l
(lowercase L
) flag:
egrep -lir --include=*.{php,html,js} "(document.cookie|setcookie)" .
Solution 2 - Bash
Try something like grep -r -n -i --include="*.html *.php *.js" searchstrinhere .
the -i
makes it case insensitlve
the .
at the end means you want to start from your current directory, this could be substituted with any directory.
the -r
means do this recursively, right down the directory tree
the -n
prints the line number for matches.
the --include
lets you add file names, extensions. Wildcards accepted
For more info see: http://www.gnu.org/software/grep/
Solution 3 - Bash
find
them and grep
for the string:
This will find all files of your 3 types in /starting/path and grep for the regular expression '(document\.cookie|setcookie)'
. Split over 2 lines with the backslash just for readability...
find /starting/path -type f -name "*.php" -o -name "*.html" -o -name "*.js" | \
xargs egrep -i '(document\.cookie|setcookie)'
Solution 4 - Bash
Sounds like a perfect job for grep
or perhaps ack
Or this wonderful construction:
find . -type f \( -name *.php -o -name *.html -o -name *.js \) -exec grep "document.cookie\|setcookie" /dev/null {} \;
Solution 5 - Bash
find . -type f -name '*php' -o -name '*js' -o -name '*html' |\
xargs grep -liE 'document\.cookie|setcookie'
Solution 6 - Bash
Just to include one more alternative, you could also use this:
find "/starting/path" -type f -regextype posix-extended -regex "^.*\.(php|html|js)$" -exec grep -EH '(document\.cookie|setcookie)' {} \;
Where:
-regextype posix-extended
tellsfind
what kind of regex to expect-regex "^.*\.(php|html|js)$"
tellsfind
the regex itself filenames must match-exec grep -EH '(document\.cookie|setcookie)' {} \;
tellsfind
to run the command (with its options and arguments) specified between the-exec
option and the\;
for each file it finds, where{}
represents where the file path goes in this command.
while
E
option tellsgrep
to use extended regex (to support the parentheses) and...H
option tellsgrep
to print file paths before the matches.
And, given this, if you only want file paths, you may use:
find "/starting/path" -type f -regextype posix-extended -regex "^.*\.(php|html|js)$" -exec grep -EH '(document\.cookie|setcookie)' {} \; | sed -r 's/(^.*):.*$/\1/' | sort -u
Where
|
[pipe] send the output offind
to the next command after this (which issed
, thensort
)r
option tellssed
to use extended regex.s/HI/BYE/
tellssed
to replace every First occurrence (per line) of "HI" with "BYE" and...s/(^.*):.*$/\1/
tells it to replace the regex(^.*):.*$
(meaning a group [stuff enclosed by()
] including everything [.*
= one or more of any-character] from the beginning of the line [^
] till' the first ':' followed by anything till' the end of line [$
]) by the first group [\1
] of the replaced regex.u
tells sort to remove duplicate entries (takesort -u
as optional).
...FAR from being the most elegant way. As I said, my intention is to increase the range of possibilities (and also to give more complete explanations on some tools you could use).