If you want to match on file names that start with m
or follow a newline character, then that would be:
NL='
'
find . \( -name 'm*' -o -name "*${NL}m*" \) -print
Note that at least with GNU find
, *
won't match a byte sequence that don't form a valid character sequence. You'd probably be better of using the C locale if that's a potential issue.
LC_ALL=C find . \( -name 'm*' -o -name "*${NL}m*" \) -print
Example:
$ touch mom $'two\nminutes' $'mad\x80'
$ find . -name 'm*'
./mom
$ find . \( -name 'm*' -o -name "*${NL}m*" \) -print
./two?minutes
./mom
$ LC_ALL=C find . \( -name 'm*' -o -name "*${NL}m*" \) -print
./mad?
./two?minutes
./mom
For file names that have a line starting with m
and not line ending with g
:
LC_ALL=C find . \( -name 'm*' -o -name "*${NL}m*" \) ! \(
-name '*g' -o -name "*g${NL}*" \) -print
Some find
implementations have some non-standard options to match the file path (usually not name) using regular expressions but the behaviour varies between implementation and those are not needed here.
Where you'd need regular expressions would be for instance to find files whose name has lines starting with m
none of which end in g
(like $'cat\nman\ndog'
but not $'plate\nmug\ncup'
nor $'cat\nman\nmug'
)
With GNU find
:
LC_ALL=C find . -regextype posix-extended -regex \
".*/(([^m$NL/][^/$NL]*|m[^/$NL]*[^$NL/g]|m|)($NL|\$))*"
Or files whose name have at least a line starting with m
and not ending in g
(like $'mad\nmug'
but not $'ming\nmong'
):
LC_ALL=C find . -regextype posix-extended -regex \
".*/([^/]*$NL)?m([^$NL/]*[^g$NL/])?(\$|${NL}[^/]*)"