Question

I have an Android project in which I have strings.xml and other .xml files defined in various places depending upon language and other criteria.

There are directories like -

> /res/values-en-rUS/strings.xml 
> /res/values-es-rUS/strings.xml
> /res/values-fi/strings.xml 
> /res/values-it/strings.xml
> /res/values-ms/strings.xml 
> /res/values-bn/strings.xml
> /res/values-da/strings.xml
> /overlay_dir/TN_KOR_COMMON/res/values/strings.xml
> /overlay_dir/TN_KOR_COMMON/res/values-en-rUS/strings.xml
> /overlay_dir/TN_KOR_COMMON/res/values-ko/strings.xml
> /overlay_dir/TN_JPN_COMMON/res/values-ja/strings.xml
> /res/layout/hovering.xml
> /res/xml/settings_menu.xml

Now, I want to find a string in only files in directories which have paths like /res/values-en-rUS and /res/xml.
I used the command -

grep -i "hovering_msg" `find -path "*@(values-en-rUS|xml)*" -iname "*.xml"`

but it doesn't seem to work. According to my understanding *@(values-en-rUS|xml)*" means find a number of characters followed by either values-en-rUS or xml followed by any number of characters. Can someone tell me where I am going wrong?

Was it helpful?

Solution

I assume that you worked in bash env. You have used extend globbing, so you have to turn it on first by:

shopt -s extglob

And for your task, you don't have to combine grep and find, you can do:

grep -i 'pattern' /res/@(values-en-rUS|xml)/*.xml

For source codes searching, I recommend ag (silver searcher).

OTHER TIPS

Pattern matching against the directory part with -path or -regex is possible as well but it would be simpler to just specify both target directories than trying to match patterns against them. This would save execution time since it wouldn't try to search files in other directories.

find /res/values-en-rUS /res/xml -iname '*.xml'

With grep:

grep -i "hovering_msg" `find /res/values-en-rUS /res/xml -iname '*.xml'`

Besides splittng output of command substitution with backquotes, it is also be possible to use while read from a pipe to also allow spaces in filenames:

find /res/values-en-rUS /res/xml -iname '*.xml' | while read file; do
    grep -i "hovering_msg" "$file"
done

If you're in a Linux box, using xargs would be the better option:

find /res/values-en-rUS /res/xml -iname '*.xml' -print0 | xargs -0 -d '\n' -- grep -i "hovering_msg" --
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top