@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不是pruned。
您可以通过以下方法解决此问题:
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不支持任意路径参数(-fFreeBSD 除外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