我要查找以某些 char 开头的所有文件,例如
find . -maxdepth 1 \( -name "^m*" -a ! -name "g$" \) -print
但是如果有人创建的文件的名称中包含特殊字符怎么办?例如
touch "
marst"
尽管它符合标准,但不会被发现。我应该如何更改代码才能找到以空格开头的文件?
也\( -name "^m*" -a ! -name "g$" \)
不起作用,因为 find 中的文件不是“marr”而是“./marr”,这意味着这将找不到任何内容。如何更改代码以匹配单词的开头?
答案1
-name
总是只匹配名称,即不匹配路径;它匹配所有的姓名。它的值是一个模式,而不是正则表达式,因此m
可以使用以下命令找到以 开头的文件名
-name 'm*'
g
以及以以下结尾的名称
-name '*g'
要使用正则表达式,请参阅-regex
选项。
答案2
如果您想匹配以换行符开头m
或后面的文件名,那么将是:
NL='
'
find . \( -name 'm*' -o -name "*${NL}m*" \) -print
请注意,至少对于 GNU find
,*
不会匹配不形成有效字符序列的字节序列。如果这是一个潜在的问题,您可能最好使用 C 语言环境。
LC_ALL=C find . \( -name 'm*' -o -name "*${NL}m*" \) -print
例子:
$ 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
对于包含以 开头m
但不包含以 结尾的行的文件名g
:
LC_ALL=C find . \( -name 'm*' -o -name "*${NL}m*" \) ! \(
-name '*g' -o -name "*g${NL}*" \) -print
某些find
实现有一些非标准选项来匹配文件小路(通常不姓名)使用正则表达式,但不同实现之间的行为有所不同,这里不需要这些。
例如,您需要正则表达式的地方是查找名称中的行开头m
不以任何结尾的文件g
(例如$'cat\nman\ndog'
但不是$'plate\nmug\ncup'
nor $'cat\nman\nmug'
)
使用 GNU find
:
LC_ALL=C find . -regextype posix-extended -regex \
".*/(([^m$NL/][^/$NL]*|m[^/$NL]*[^$NL/g]|m|)($NL|\$))*"
或者名称至少有一行以以下开头m
且不以以下结尾的文件g
(类似于$'mad\nmug'
但不是$'ming\nmong'
):
LC_ALL=C find . -regextype posix-extended -regex \
".*/([^/]*$NL)?m([^$NL/]*[^g$NL/])?(\$|${NL}[^/]*)"
答案3
您可以使用该-regex
标志来查找是否需要 glob 提供的更复杂的匹配。它与整个路径匹配,所以如果您只想匹配文件名部分,您可以执行类似的操作
find . -maxdepth 1 -regex '/[
]?m[^/]*[^g]$' -print
请注意,每这个答案你不能用来\n
匹配换行符,所以我们在我们的字符类中放置了一个带有空格的换行符,因为你已经要求了。
答案4
在 find 中,您不需要使用 the^
或 the$
作为简单名称。
寻找用途模式对于名字。模式将:
- 匹配整个名字。从开始到结束。总是。
- find 删除在使用该模式之前找到的任何文件的路径。
- 唯一的特殊字符是
*
?
and[ ]
(不是 ^ 或 $)。
m
因此,对于以and开头的匹配文件不是以g
:结束
find . -maxdepth 1 -name 'm*[!g]' -o -name 'm'
涵盖'm'
文件只有一个字符的情况。
但是,您创建的文件touch $'\nmarst'
(是的,可以像 bash 中那样编写换行符)不以 开头m
,而是以 new-line 开头$'\n'
。没有办法在简单模式中进行交替,但您可以使用-o
find 的 OR ( ) 选项:
find . -maxdepth 1 \( -name 'm*' -o -name $'\n'"m*" \) -a ! -name '*g'
如果要求更长,这将变得困难。
对于非常复杂的字符串,可以-regex
使用 find 选项。