2

I have a files:

first.error.log
second1.log
second2.log
FFFpc.log
TR.den.log
bla.error.log

and I would like to make a pattern that will match all files with error inside of filenames + few additional ones but no more:

For a sole error it would be

 $FILE_PATTERN="*.error*"  

But what if I want to match not only those errors but also all second and FFpc etc?

This does not work:

$FILE_PATTERN="*.error*|^second.*\log$|.*FFPC\.log$" 

Thanks in advance for your help

EDIT:

$FILE_PATTERN is later used by:

find /somefolder -type f -name $FILE_PATTERN

EDIT: THIS FILE_PATTERN is in property file that is later used by bash script.

Mateusz Chrzaszcz
  • 1,240
  • 14
  • 32
  • What command is using `$FILE_PATTERN`? – Explosion Pills Aug 06 '14 at 14:14
  • I don't understand what you want to match. You're using a mishmash of regex and wildcards without explanation, it's a terrible idea for conveying intent. If you used proper regex it would work (`.` means one character, `.*` means a string, `\.` means a dot). – Blindy Aug 06 '14 at 14:16

5 Answers5

2

You need to use find with -regex option:

find -E /somefolder -type f -regex '\./(.*\.error.*|second.*log|.*FFPC\.log)$'

PS: Use -iregex for ignore case matching:

find -E /somefolder -type f -iregex '\./(.*\.error.*|second.*log|.*FFPC\.log)$'
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • `-E` is for extended regular expression. – anubhava Aug 06 '14 at 14:32
  • 1
    I see. GNU `find` doesn't have it I think. With GNU, you do it with `-regextype ` where type can be `findutils-default`, `awk`, `egrep`, `ed`, `emacs`, `gnu-awk`, `grep`, `posix-awk`, `posix-basic`, `posix-egrep`, `posix-extended`, `posix-minimal-basic`, `sed`. – konsolebox Aug 06 '14 at 14:38
  • 1
    @konsolebox: Many thanks for adding note about `gnu find`. I was on OSX so couldn't test it using `gnu` version of `find`. – anubhava Aug 06 '14 at 14:40
  • Actually, the main problem was that -name in a find command instead of -regex, after I changed it everything else went smoothly, thanks! – Mateusz Chrzaszcz Aug 06 '14 at 15:10
  • 1
    Yes that is true @MateuszChrzaszcz. What you has was indeed a regex pattern not a glob pattern. – anubhava Aug 06 '14 at 15:13
1
$ ls | grep -i '\(.*error.*\)\|\(^second.*\log$\)\|\(.*FFPC\.log$\)'
bla.error.log
FFFpc.log
first.error.log
second1.log
second2.log

If you wanted to use with find

find /somefolder -type f | grep -i '\(.*error.*\)\|\(^second.*\log$\)\|\(.*FFPC\.log$\)'
Hemang
  • 1,351
  • 1
  • 10
  • 20
1

If you're in bash I'm assuming you have to grep. Using grep -E or egrep will allow you to use alternation (ORing your searches)

$ stat * | egrep "(error|second)"
File: `first.error.log'
File: `second1.log'
File: `second2.log'

You could use ls instead of stat but sometimes ls will not give you what you predicted. But considering you're only search for filenames, ls should suffice.

$ ls | egrep "(error|second)"
first.error.log
second1.log
second2.log

You can use command substitution to store the output into a bash variable:

FILE_PATTERN=$(ls | egrep "(error|second)")
skamazin
  • 757
  • 5
  • 12
1
FILE_PATTERN=("*.error*" "second.*log" ".*FFPC.log")
ARGS=(-name "$FILE_PATTERN")
for F in "${FILE_PATTERN[@]:2}"; do
    ARGS+=(-o -name "$F")
done
find /somefolder -type f '(' "${ARGS[@]}" ')'
konsolebox
  • 72,135
  • 12
  • 99
  • 105
0

You were close, theres just a few misplaced symbols.

Here's what I came up with:

.*\.error\..*|^second.*\.log$|.*FF[Pp][Cc]\.log$

here's a demo of a working modification of your regex: http://regex101.com/r/rL3rM1/1

Adam Yost
  • 3,616
  • 23
  • 36