How can I find the directories where a text is found in a specific file? E.g. I want to get all the directories in "/var/www/" that contain the text "foo-bundle" in the composer.json
file. I have a command that already does it:
find ./ -maxdepth 2 -type f -print | grep -i 'composer.json' | xargs grep -i '"foo-bundle"'
However I want to make an sh
script that gets all those directories and do things with them. Any idea?
CodePudding user response:
find
Your current command is almost there, instead off using xargs
with grep
, lets:
find ./ -maxdepth 2 -type f -exec grep -l "foo-bundle" {} /dev/null \; | xargs dirname
If you only want to search for composer.json
files, we can include the -iname
option like so:
find ./ -maxdepth 2 -type f -iname '*composer.json' -exec grep -l "foo-bundle" {} /dev/null \; | xargs dirname
If the | xargs dirname
doesn't give enough data, we can extend it so we can loop over the results of find
using a while read
like so:
find ./ -maxdepth 2 -type f -iname '*composer.json' -exec grep -l "foo-bundle" {} /dev/null \; | while read -r line ; do
parent="$(dirname ${line%%:*})"
echo "$parent"
done
grep
We can use grep to search for all files containing a specific text.
After looping over each line, we can
- Remove behind the
:
to get the filepath - Use
dirname
to get the parent folder path
Consider this file setup, were /test/b/composer.json
contains foo-bundle
➜ /tmp tree
.
├── test
│ ├── a
│ │ └── composer.json
│ └── b
│ └── composer.json
└── test.sh
When running the following test.sh
:
#!/bin/bash
grep -rw '/tmp/test' --include '*composer.json' -e 'foo-bundle' | while read -r line ; do
parent="$(dirname ${line%:*})"
echo "$parent"
done
The result is as expected, the path to folder b
:
/tmp/test/b
CodePudding user response:
In order to find all files, containing a particular piece of text, you can use:
find ./ -maxdepth 2 -type f -exec grep -l "composer.json" {} /dev/null \;
The result is a list of filenames. Now all you need to do is to get a way to launch the command dirname
on all of them. (I tried using a simple pipe, but that would have been too easy :-) )
CodePudding user response:
Thanks to @0stone0 for leading the way. I finally got it with:
#!/bin/sh
find /var/www -maxdepth 2 -type f -print | grep -i 'composer.json' | xargs grep -i 'foo-bundle' | while read -r line ; do
parent="$(dirname ${line%%:*})"
echo "$parent"
done