How can I use a POSIX BRE or a POSIX ERE regex to match a string(line or word) that does not have bak at the end?I want to do a ls | egrep '<regex>' to find all files which DO NOT have bak at the end of the filename. For example, if there are three files file1, file2_bak, and bak_file3, the regex should match only file1 and bak_file3 (but not file2_bak).I know that this can be done with ls | grep -v 'bak$', but I want to do this without using -v option for grep or egrep. I dont want to use -v because this is just a theoretical/academic question on POSIX regexes. This is how I match the filenames which DO HAVE bak at the end:$ ls | egrep 'bak$'file2_bak$ The above regex, bak$, matches all strings that DO HAVE bak at the end. But how can I write a regex which matches all strings that do not have bak at the end?
How to use a regex to match a pattern which does not have a specific string at the end
grep;regular expression
Regular languages (i.e. this can be matched with a RE) are closed under complement, so it's possible, but it's not very useful for practical purposes: what you start out with is the conditionlast letter is k AND letter before that is a AND letter before that is b(let me write s[-1]=='k' and s[-2]=='a' and s[-3]=='b' in a pythonesque fashion)so a string that fails that hasnot(s[-1]=='k' and s[-2]=='a' and s[-3]=='b')i.e.not(s[-1]=='k') or not (s[-2]=='a' and s[-3]=='b'))i.e.not(s[-1]=='k') or not(s[-2]=='a') or not(s[-3]=='b')applying deMorgan's rule twice, and of course, this would in particular be the case if your string has length 2 or less, so you would roughly end up withgrep '^$\|^.$\|^..$\|..[^k]$\|.[^a].$\|[^b]..$'which I'd consider typeable but unmaintainable.(Theoretical sidenote: in general, you'd convert your regular expression into a deterministic finite automaton (DFA), invert the terminal states there, and then convert the new DFA back into a regular expression, which is all well-defined, but a somewhat tedious and error-prone process.)