Why does this fail?

touch "$(printf "a\nb")"; find . -regex './.\n.'

I also tried these, none of which work:

find . -regextype posix-extended -regex '.\n.'
find . -regextype posix-awk -regex '.\n.'
find . -regextype posix-basic -regex '.\n.'
find . -regextype posix-egrep -regex '.\n.'

The only way it seems to work is (thanks @MichaelMrozek)

find . -regex './.'$'\n''.'

Which is cumbersome to say the least. So, why do find's regular expressions seem to be unable to deal with \n?

Update in response to answers so far:

OK, I understand that \n is not part of ERE and that was one of my misunderstandings but find claims to support posix-awk and both gawk and mawk match \n as expected:

$ printf "f1l1\nhas newline:f2l1#f1l2 does not:f2l2#" | 
    mawk -F: 'BEGIN{RS="#"}; ($1~/\n/){print $1}' 
has newline

I don't have a pure awk to test with so perhaps POSIX awk does not match? Otherwise is find not actually implementing posix-awk regular expressions?

  • Is find . -name $'*\n*' cumbersome too?
    – devnull
    Commented Mar 10, 2014 at 17:07
  • Not at all, just irrelevant. I am wondering why -regex fails, not How to find files that contain newline in filename? which you answered perfectly :).
    – terdon
    Commented Mar 10, 2014 at 17:10
  • After discussing this with some other users in chat, it seems likely that the awk regex language does not know about \n but that the awk interpreter does and that's why it matches. Therefore, implementing awk regexes as find does, would not imply that \n should match. Thank you all!
    – terdon
    Commented Mar 10, 2014 at 17:54

3 Answers 3


Because GNU find doesn't support \n as an escape sequence. The regexp \n matches the character n. GNU find copies the traditional Emacs syntax, which doesn't have this feature either¹.

While GNU find supports other regex syntax, none support backslash-letter or backslash-octal to denote control characters. You need to include the control character literally in the argument.

There are many different regex syntaxes around. Neither POSIX basic regular expressions (BRE) nor extended regular expressions (ERE) include \n or backslash-octal escapes. Both definitions leave the meaning of backslash when not followed by a special character undefined. The utilities awk and sed both support \n to mean a newline; this is specific to these utilities (and commonplace, but as you see not universal).

From a shell script, you can write

find . -regex $'./.\n.'     # ksh/bash/zsh only
find . -regex './.
find . -name '*

¹ Quite logically: for interactive use, you can type any character with C-q; for programming use, \n exists as part of the string literal syntax.

  • Are basic regular expressions and extended regular expressions not the kind used in grep?
    – Melab
    Commented Sep 30, 2017 at 15:17
  • @Melab grep uses BRE by default, or ERE with the option -E. Commented Oct 1, 2017 at 17:33

You can't match a newline with '\n' because it has no special meaning in a regular expression (break line for example), but you can match the end of line with $ regular expression.

  • \n most certainly does have a meaning in a regex, try printf "aa\nbb" | perl -ne 'print if /\n/', that will only match aa\n and skips the bb for example. There do seem to be differences in implementation though cause grep -P won't match that. But how is $ relevant here? I want to match a literal newline, $ matches even in the absence of one: printf "aa" | grep 'a$'
    – terdon
    Commented Mar 10, 2014 at 17:17
  • 1
    @terdon \n has no special meaning, even in Perl regular expressions. It does, however, have special meaning in interpolated perl strings, of which qr// is one type. Search for \n in man perlre...
    – derobert
    Commented Mar 10, 2014 at 17:20
  • @derobert fair point, I expressed myself badly. I meant that \n matches newlines in regular expressions. You and babaslovesyou are quite right that it has no special meaning as such, I just mean that is is "matchable" .
    – terdon
    Commented Mar 10, 2014 at 17:22
  • 2
    @terdon Well, except you're trying to match the character 0x0A (newline), and you're trying to do it with the character sequence 0x5C (backslash) 0x6E (n). Since \n has no special meaning, it tries to match itself. The \ may or may not get stripped out (invalid escape) depending on RE engine, but you're trying to match <NL> vs \n or n, neither matches.
    – derobert
    Commented Mar 10, 2014 at 17:27
  • 2
    @terdon in your Perl example, what's actually happening is that the string parsing is turning \n into <NL>, before passing it off to the regexp engine. That's a feature of Perl string parsing.
    – derobert
    Commented Mar 10, 2014 at 17:28

I think because find using fnmatchfunction in standard C library, so if FNM_NOESCAPE is not set, a backslash character in pattern followed by any other character will match that second character in string.


Don't treat the `\' character specially in patterns. Normally, `\' quotes
the following character, turning off its special meaning (if any) so that it 
matches only itself. When quoting is enabled, the pattern `\?' matches only 
the string `?', because the question mark in the pattern acts like an 
ordinary character. If you use FNM_NOESCAPE, then `\' is an ordinary character.

I check with find (GNU findutils) 4.4.2 and glibc 2.15, this option is off. check line 42 in fnmatch.h:

#define FNM_NOESCAPE    (1 << 1) /* Backslashes don't quote special chars.  */
  • fnmatch is for *.txt type of patterns, not .*\.txt$ type regexps. Commented Mar 10, 2014 at 20:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .