0

I search SO for something that might give me this simple answer and it seems to be here and here (among many) but I simply can not get it to work.

I have files like

12_pattern1.yyy_zzz #find
13_pattern1.xxx.pattern2_xx 
12_yy_pattern1:xxx
14_pattern1.xxx_pattern2.xxx #find
12_xxx_zzz.yyy.xxx
14_pattern1.xxx.yyy #find

I need to find and remove files that start with 12 or 14, have _pattern1 immediately hereafter and do NOT end with pattern2.

I tried something along find . -regex ".*/\(12_\|14_\)pattern1.*[^pattern2$]" -exec rm -f {} \;

What am I missing here ?

user3375672
  • 3,728
  • 9
  • 41
  • 70

2 Answers2

3

How about something like this:

find . -regex "^\(12_\|14_\)pattern1.*" -not -regex "*.pattern2$"
Mithrandir
  • 24,869
  • 6
  • 50
  • 66
  • Ah yes! This is perfect - I was trying to get it into the the one regex (just to be annoying: can you put the -not into the first regex as I tried?) – user3375672 May 16 '18 at 15:04
  • You can have a negated character class, but you can't simply negate a pattern in a regular expression. As far as i'm aware this is the only reasonable way to do it. – Mithrandir May 16 '18 at 15:08
1

find command supports posix-* flavors for Regular Expressions. It means you can't do it simply with find. However, if you could use grep then you could do it easily (but with help of two tools):

find . | grep -P '(14|12)_pattern1[^/]*$(?<!pattern2)'
revo
  • 47,783
  • 14
  • 74
  • 117