@meuh的方法效率低下,因为他的-maxdepth 1
方法仍然允许find
读取级别1的目录的内容,以后再忽略它们。如果某些目录名称包含在用户区域设置中不构成有效字符的字节序列(例如,采用不同字符编码的文件名),则它也不适用于某些find
实现(包括GNU find
)。
find . \( -name . -o -prune \) -extra-conditions-and-actions
是实现GNU -maxdepth 1
(或FreeBSD -depth -2
)的更规范的方法。
虽然一般来说,是-depth 1
您想要(-mindepth 1 -maxdepth 1
),因为您不想考虑.
(深度0),所以它甚至更简单:
find . ! -name . -prune -extra-conditions-and-actions
对于-maxdepth 2
,则变为:
find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
这就是您运行无效字符的地方。
例如,如果您有一个目录,Stéphane
但是é
在2000年代中期之前在西欧和美洲最常见,但使用iso8859-1(aka latin1)字符集(0xe9字节)进行编码,则该0xe9字节不是UTF-8中的有效字符。因此,在UTF-8语言环境中,*
通配符(在某些find
实现中)将不匹配,Stéphane
因为*
0个或多个字符和0xe9不是字符。
$ locale charmap
UTF-8
$ find . -maxdepth 2
.
./St?phane
./St?phane/Chazelas
./Stéphane
./Stéphane/Chazelas
./John
./John/Smith
$ find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St?phane/Chazelas/age
./St?phane/Chazelas/gender
./St?phane/Chazelas/address
./Stéphane
./Stéphane/Chazelas
./John
./John/Smith
我的find
(当输出到达终端时)显示无效的0xe9字节,?
如上所述。您可以看到St<0xe9>phane/Chazelas
不是prune
d。
您可以通过以下方法解决此问题:
LC_ALL=C find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
但是请注意,这会影响该find
程序及其运行的所有应用程序的所有语言环境设置(例如通过-exec
谓词)。
$ LC_ALL=C find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St??phane
./St??phane/Chazelas
./John
./John/Smith
现在,我确实得到了一个提示,-maxdepth 2
但请注意,第二个Stéphane中的é如何正确显示为??
é的UTF-8编码的0xc3 0xa9字节(在C语言环境中被视为两个单独的未定义字符), C语言环境中不可打印的字符。
如果添加了-name '????????'
,我会得到错误的Stéphane(iso8859-1中编码的那个)。
要应用于任意路径而不是.
,您可以执行以下操作:
find some/dir/. ! -name . -prune ...
为-mindepth 1 -maxdepth 1
或:
find some/dir/. \( ! -path '*/./*/*' -o -prune \) ...
为-maxdepth 2
。
我仍然会做:
(cd -P -- "$dir" && find . ...)
首先,因为这会使路径更短,这使得它不太可能遇到路径太长或arg列表太长的问题,而且还可以解决以下事实:find
不支持任意路径参数(-f
FreeBSD 除外find
),因为它会阻塞$dir
喜欢!
或-print
...的值
在-o
与否定组合是一个常见的特技运行两个独立的组-condition
/ -action
中find
。
如果要-action1
在文件会议上运行-condition1
并独立-action2
在文件会议上运行-condition2
,则不能执行以下操作:
find . -condition1 -action1 -condition2 -action2
至于-action2
将仅适用于符合文件中运行这两个条件。
也不:
find . -contition1 -action1 -o -condition2 -action2
对于同时-action2
满足两个条件的文件将不会运行。
find . \( ! -condition1 -o -action1 \) -condition2 -action2
工作原理\( ! -condition1 -o -action1 \)
将解析为真正的每个文件。这假设-action1
是一个动作(如-prune
,-exec ... {} +
),它总是返回真。对于这样的行为-exec ... \;
可能返回错误,你可能要添加另一个-o -something
地方-something
是无害的,但返回真像-true
在GNU find
或-links +0
或 -name '*'
(但要注意上面关于无效字符的问题)。
-depth -2
,-depth 1
...做法可以被看作是比GNU的好-maxdepth
/-mindepth