11

I have got the following Problem.

I´m doing a grep like:

$command = grep -r -i --include=*.cfg 'host{' /omd/sites/mesh/etc/icinga/conf.d/objects

I got the following output:

/omd/sites/mesh/etc/icinga/conf.d/objects/testsystem/test1.cfg:define host{
/omd/sites/mesh/etc/icinga/conf.d/objects/testsystem/test2.cfg:define host{
/omd/sites/mesh/etc/icinga/conf.d/objects/testsystem/test3.cfg:define host{
...

for all *.cfg files.

With exec($command,$array)

I passed the result in an array.

Is it possible to get only the filenames as result of the grep-command.

I have tried the following:

$Command=    grep -l -H -r -i --include=*.cfg 'host{' /omd/sites/mesh/etc/icinga/conf.d/objects

but I got the same result.

I know that on the forum a similar topic exists.(How can I use grep to show just filenames (no in-line matches) on linux?), but the solution doesn´t work.

With "exec($Command,$result_array)" I try to get an array with the results. The mentioned solutions works all, but I can´t get an resultarray with exec().

Can anyone help me?

Community
  • 1
  • 1
Thomas Lang
  • 231
  • 1
  • 4
  • 12

3 Answers3

18

Yet another simpler solution:

grep -l whatever-you-want | xargs -L 1 basename

or you can avoid xargs and use a subshell instead, if you are not using an ancient version of the GNU coreutils:

basename -a $(grep -l whatever-you-want)

basename is the bash straightforward solution to get a file name without path. You may also be interested in dirname to get the path only.

GNU Coreutils basename documentation

olivecoder
  • 2,858
  • 23
  • 22
5

Is it possible to get only the filenames as result of the grep command.

With grep you need the -l option to display only file names.

Using find ... -execdir grep ... \{} + you might prevent displaying the full path of the file (is this what you need?)

find /omd/sites/mesh/etc/icinga/conf.d/objects -name '*.cfg' \
     -execdir grep -r -i -l 'host{' \{} +

In addition, concerning the second part of your question, to read the result of a command into an array, you have to use the syntax: IFS=$'\n' MYVAR=( $(cmd ...) )

In that particular case (I formatted as multiline statement in order to clearly show the structure of that expression -- of course you could write as a "one-liner"):

IFS=$'\n' MYVAR=(
    $(
        find objects -name '*.cfg' \
                     -execdir grep -r -i -l 'host{' \{} +
    )
)

You have then access to the result in the array MYVAR as usual. While I while I was testing (3 matches in that particular case):

sh$ echo ${#MYVAR[@]}
3
sh$ echo ${MYVAR[0]}
./x y.cfg
sh$ echo ${MYVAR[1]}
./d.cfg
sh$ echo ${MYVAR[2]}
./e.cfg
# ...
Sylvain Leroux
  • 50,096
  • 7
  • 103
  • 125
  • Your suggested string works! Thank you. I have got one more question: -I try to get the result as an array -I tried to execute your string as following: $shellCommand=find /omd/sites/mesh/etc/icinga/conf.d/objects -name '*.cfg' \ -execdir grep -r -i -l 'host{' \{} +
    exec($shellCommand, $hostname);
    – Thomas Lang Jul 18 '14 at 07:44
  • 1
    @ThomasLang Like the other answerers, I missed the second part of your question. Maybe you should have posted _two_ separate questions? Anyway I've fixed my answer to add that part. Hope this help. – Sylvain Leroux Jul 18 '14 at 10:18
  • at the second look at my question I saw that I have forgotten the second part. So I added it later. I hope this was not to confusing. – Thomas Lang Jul 18 '14 at 11:21
0

This should work:

grep -r -i --include=*.cfg 'host{' /omd/sites/mesh/etc/icinga/conf.d/objects | \
    awk '{print $1}' | sed -e 's|[^/]*/||g' -e 's|:define$||'

The awk portion finds the first field in it and the sed command trims off the path and the :define.

djhaskin987
  • 9,741
  • 4
  • 50
  • 86