3

I am trying to get the output of files from today which contain "ERROR".

I use this to find the files I want:

find /home/user/logfilesError/ -maxdepth 1 -type f -name "gandalf_*"\
   -daystart -mtime -1 -exec grep -rl "ERROR" "{}" +

Current output (if ERROR found):

/home/user/logfilesError/gandalf_123.log

But the output I want is only the logfile name:

gandalf_123.log

Info: The path changes often so I can't just cut the letters before.

Thanks for your help!

2
  • I think the grep -rl especially the -l stops after at the first match
    – BlueFox
    Jun 18 '14 at 10:20
  • 1
    I edited my answer. How to output the answers separated by a comma is a different question. I think the answer has already been given somewhere. One way to do it is to pipe your output to awk 'BEGIN {ORS=", "} ; {print} ; NR=$NR { ORS="\n" }'
    – lgeorget
    Jun 18 '14 at 11:22
2

The basename tool can strip the path before the filename.

find /home/user/logfilesError/ -maxdepth 1 -type f -name "gandalf_*"\
-daystart -mtime -1 -exec grep -rl "ERROR" "{}" + | xargs -n 1 basename

will give you the desired output.

-n 1 tells xargs to use exactly one argument for basename. So if it receives more, it will spawn one basename process per argument. This is needed as basename takes only one filename as argument.

This command will NOT work if your filenames contain spaces. In this case, as suggested by @HaukeLaging, use :

find /home/user/logfilesError/ -maxdepth 1 -type f -name "gandalf_*"\
-daystart -mtime -1 -exec grep -rl "ERROR" "{}" + | xargs -n 1 -d \\n basename

This will not work if your filenames contain newlines, though.

6
  • 2
    xargs -d \\n basename Jun 18 '14 at 9:22
  • @HaukeLaging Coool, how comes -d is not documented in the man page?
    – lgeorget
    Jun 18 '14 at 9:26
  • It is (and "always" has been) in mine... (--delimiter=delim, -d delim) Jun 18 '14 at 9:30
  • @HaukeLaging Well... just figured out, I was looking at my localized (french) man page, which is apparently not up-to-date.
    – lgeorget
    Jun 18 '14 at 9:32
  • Can someone help me with the edit? I dont know why there should only be one output.
    – BlueFox
    Jun 18 '14 at 10:08
1

If ./gandalf_123.log is OK for you then you can use

find /home/user/logfilesError/ -maxdepth 1 -type f -name "gandalf_*"\
  -daystart -mtime -1 -execdir grep -rl "ERROR" "{}" +

Otherwise I would pipe the grep output through e.g. sed in order to delete the unwanted part:

> echo /home/user/logfilesError/gandalf_123.log |
  sed 's+.*/++'
gandalf_123.log
1

You can use sed:

... | sed -e 's=.*/=='

Which tells it to replace anything up to a / with nothing.

You can also use cut, but it can't count from the right, so you have to combine it with rev:

... | rev | cut -d/ -f1 | rev
0

this can be done with

 echo ${str##*/}

which will trim the string from left to right until last '/'

> str=/home/user/logfilesError/gandalf_123.log
> echo ${str##*/}
gandalf_123.log

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.