dscl
dscl

Reputation: 1626

Grep search strings with line breaks with the Find command

I'm trying to search within all settings.ini files and determine which of them contain a specific multiline string.

My directory structures look like this

/
|-- folder
|---- settings.ini
|-- folder
|---- settings.ini
|-- folder
|---- settings.ini
|-- folder
|---- settings.ini
.
.
.

The string I am trying to find looks like this

[NeatFeature]
Enabled=1

The files themselves will contain either Enabled=1 or Enabled=0

I'm able to get a single line search working like this

find . -maxdepth 2 -name 'settings.ini' -exec grep '\[TransactionalMessageSearch\]' {} +

The problem is I can't figure out how to also include the Enabled=1 portion. I can't just search for that on it's own as that patter occurs multiple times throughout the files under different headings.

Any ideas?

Upvotes: 0

Views: 365

Answers (4)

dscl
dscl

Reputation: 1626

Thanks to a suggestion by Mark, I was able to then pipe the output and get grep through that to get to the result set I was looking for

find . -maxdepth 2 -name 'settings.ini' -exec grep -HA 1 '\[TransactionalMessageSearch\]' {} \; | grep 'Enabled=1'

Upvotes: 1

Mark Setchell
Mark Setchell

Reputation: 207465

Perl Method

perl -0777 -ne 's/.*\[TransactionalMessageSearch]\nEnabled=(\d)//s;print $1' settings.ini

Original Answer

You can also do this with gawk and test more than one file per invocation, using find's + feature:

Save this as a file called FeatureTest

#!/bin/bash
awk -F'=' '/\[TransactionalMessageSearch\]/{armed=1} armed==1 && /Enabled/{print FILENAME":"$2;armed=0;nextfile}' "$@"

then do this to make it executable

chmod +x FeatureTest

then you can do:

find . -name 'settings.ini' -exec ./FeatureTest {} +

The nextfile function is part of GNU awk, and I don't know of a way to do that without, so you would have to settle for the slower version as follows if you do not have GNU awk.

#!/bin/bash
awk -F'=' '/\[TransactionalMessageSearch\]/{armed=1} armed==1 && /Enabled/{print FILENAME":"$2;exit}' "$1"

and use it with:

find . -name 'settings.ini' -exec ./FeatureTest {} \;

The awk script basically looks for the string [Transact...] and when it finds it, it arms itself ready for the next occurrence of the word Enabled. When it finds that, after being armed, it prints the second field and the filename and moves to the next file (or exits). The fields are separated by an = sign because of the -F at the start.

Upvotes: 1

COLINHY
COLINHY

Reputation: 395

Try this:

find . -name 'settings.ini' | xagrs grep 'Enabled=1' 

Upvotes: 1

Mark Setchell
Mark Setchell

Reputation: 207465

Try adding -A to add some lines after the match maybe:

grep -A 2 xyz file

It depends how many lines there may be between the search string and the additional information.

Upvotes: 1

Related Questions