We want to capture all logs that ended with ".log.[any number]

So I create this syntax

find .  -type f  -regex '^.log.*[0-9]$' -print

command does not give any output 

But this doesn't capture the files as the following ( expected results )


what is wrong with my syntax ?

  • why do we use ^ and . should be escaped – msp9011 Aug 29 '18 at 10:14
  • 1
    Why use a regex? find /var/log -type f -name *.log.*[0-9] No escaping of dots needed, etc. If you want to find Logs LOGS and logs, then change the -name to -iname – ivanivan Aug 29 '18 at 21:53

-regex (a GNU extension also recognised by some other find implementations nowadays but with major differences) is like -path except that it uses regexps instead of wildcards. It matches on the whole file path, not just its name.

So .*\.log.*[0-9] (no need for ^ or $ by the way, they're implicit with find's -regex) would match on ./dir/foo.log-3 but also ./foo.logic/file.bz2, where the .* captured ic/file.bz.

-name matches on the file name only, uses wildcards but doesn't have a regexp counterpart. Here, for files whose name contain .log and end in a digit, you don't need regexps anyway, -name '*.foo*[0-9]'.

You can do the same with regexps though with -regex '.*\.log[^/]*[0-9]', that is making sure the part between .log and the final digit doesn't contain any / so it matches on the file name only.

With -regex, you can go further in specifying the patterns, especially if you enable extended regexps, using -E with some BSD's find or -regextype posix-extended with GNU find.

find . -regextype posix-extended -regex '.*\.log([.-][0-9]+)+' # GNU
find -E . -regex '.*\.log([.-][0-9]+)+' # BSD

Here matching on .log followed by one or more .<number> or -<number>.

Without -regextype posix-extended GNU find's regexps are emacs regexps, some sort of hybrid between standard basic regexps and standard extended regexps (supports +, but grouping is with \(...\) instead of (...)).

Without -E BSD find regexps are standard basic regexps.



find .  -type f   -regex  ".*\.log\..*[0-9]$"
  • we need to escape the .
  • this syntax not works – yael Aug 29 '18 at 10:31
  • @yeal can you share the error – msp9011 Aug 29 '18 at 10:33
  • it si just print only the file - gc.log.0 , but all other are not printed – yael Aug 29 '18 at 10:34
  • yes I already did it – yael Aug 29 '18 at 10:38
  • what you mean ? – yael Aug 29 '18 at 10:48

If after "log" there's only digits, ., and -, the following might work as well

find .  -type f   -regex  ".*[.]log[-.0-9]*$" 

You could search for your files using the following way without recourse to non-GNU find:

find . -type f \
    \( -name '?*.log.[0-9]' -o \
       \( \
           -name '?*.log.[0-9]*[0-9]'  \
         ! -name '?*.log.?*[!0-9.-]*?' \
         ! -name '?*.log.?*[.-][.-]*?' \
       \) \
    \) \

What this does is do a multi-layered filtering of the filenames caught by it and progressively shrinks the catch and zeroes in on the required. To be precise:

  • Right away select any file whose basename, i.e., w/o it's path ends in a .log.single_digit
  • OTW, select those that end in .log. NUM anything NUM This will set the trend for the filenames to be caught in the net.
  • Out of the above catch, reject those which happen to have a non number, non dash, or non dot in the anything portion of the filename. Note the trend of beginning and ending with a digit must be honored.
  • Now our catch has all those files in which anything portion comprises only digit(s), dot(s), and dash(s). The last constraint is that the dot or dash must not have each as their immediate neighbors to both their left and right.
  • P.S. Note that -name option looks at the basename portion of the filename only, AND
  • -name portion operates on the wildcard basis and hence they are implicitly anchored, meaning the name matched is full.

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.