请考虑以下示例:
mkdir /tmp/test2 && cd /tmp/test2
mkdir -p aa/{tmp,src}
mkdir -p bb/aa/{tmp,src}
mkdir -p {dd,ee}/bb
touch {dd,ee}/bb/aa
tree | awk '{print "# " $0}'
# .
# ├── aa
# │ ├── src
# │ └── tmp
# ├── bb
# │ └── aa
# │ ├── src
# │ └── tmp
# ├── cc
# │ └── aa
# │ ├── src
# │ └── tmp
# ├── dd
# │ └── bb
# │ └── aa
# └── ee
# └── bb
# └── aa
#
# 16 directories, 2 files
因此,我想找到所有名为的项目aa
,并以与相同的格式将它们打印出来ls -la
,这样我就可以知道它们是文件还是目录。
如果我使用典型的find
-exec
那么ls -a
目录本身就不会打印为项目,而是其内容如下:
$ find . -name aa -exec ls -la {} \;
total 0
drwxr-xr-x 1 user None 0 Feb 19 11:59 .
drwxr-xr-x 1 user None 0 Feb 19 12:00 ..
drwxr-xr-x 1 user None 0 Feb 19 11:59 src
drwxr-xr-x 1 user None 0 Feb 19 11:59 tmp
total 0
drwxr-xr-x 1 user None 0 Feb 19 11:59 .
drwxr-xr-x 1 user None 0 Feb 19 11:59 ..
drwxr-xr-x 1 user None 0 Feb 19 11:59 src
drwxr-xr-x 1 user None 0 Feb 19 11:59 tmp
total 0
drwxr-xr-x 1 user None 0 Feb 19 11:59 .
drwxr-xr-x 1 user None 0 Feb 19 11:59 ..
drwxr-xr-x 1 user None 0 Feb 19 11:59 src
drwxr-xr-x 1 user None 0 Feb 19 11:59 tmp
-rw-r--r-- 1 user None 0 Feb 19 12:00 ./dd/bb/aa
-rw-r--r-- 1 user None 0 Feb 19 12:00 ./ee/bb/aa
如果我改用,ls -lad {}/
那么我明确地只打印出目录节点,那么文件节点根本就不会打印,而是收到错误“不是目录”:
$ find . -name aa -exec ls -lad {}/ \;
drwxr-xr-x 1 user None 0 Feb 19 11:59 ./aa/
drwxr-xr-x 1 user None 0 Feb 19 11:59 ./bb/aa/
drwxr-xr-x 1 user None 0 Feb 19 11:59 ./cc/aa/
ls: cannot access './dd/bb/aa/': Not a directory
ls: cannot access './ee/bb/aa/': Not a directory
bash
如果我直接在命令行上尝试某种条件,它会失败:
# test
$ [ -d aa ] && echo dir || echo file
dir
$ find . -name aa -exec [ -d {} ] && ls -lad {}/ || ls -la {} \;
find: missing argument to `-exec'
ls: cannot access '{}': No such file or directory
ls: cannot access ';': No such file or directory
那么,我该如何使用find . -name aa
,最终我得到这个输出:
drwxr-xr-x 1 user None 0 Feb 19 11:59 ./aa/
drwxr-xr-x 1 user None 0 Feb 19 11:59 ./bb/aa/
drwxr-xr-x 1 user None 0 Feb 19 11:59 ./cc/aa/
-rw-r--r-- 1 user None 0 Feb 19 12:00 ./dd/bb/aa
-rw-r--r-- 1 user None 0 Feb 19 12:00 ./ee/bb/aa
您几乎已经完成了:
您需要该
-d
选项,但请省略结尾的/
。您也可以省略
-a
不需要的选项。因此这可以正常工作:
但是,对于每个项目,都会调用 。您应该
\;
改用,这样就会使用允许的最大参数数量进行调用:ls
+
ls
添加
-p
以获取输出中的尾随/
(感谢@Stéphane Chazelas),但这不是必需的,因为您可以将文件与目录d
与权限信息的开头分开。另外,您可以使用
-ls
选项find
,但这会产生略有不同的输出。请注意,这是一个常见但不是 的标准选项find
。我喜欢pLumo 的回答。
只是您可能甚至不需要
find
这一点。在 Bash 中:
在zsh中:
当然,
ls
您不必使用 来找出哪些是目录,而是只需按它们进行过滤即可。使用find
,这将find -name aa -type d
仅列出目录,并find -name aa -type f
仅列出文件。使用 zsh:
(使用内置函数在olumn上
print
打印r
aw是没有必要的;还要注意ullglob 以避免错误,如果没有匹配则不打印任何内容)。1
C
ls
N
在 bash 中,稍微复杂一些:
请注意,对于最终解析为常规文件的符号链接,
&& ! -L "${entry}"
排除符号链接-f file
也会返回 true。这是模仿或或的 glob 限定符的行为find
。-type f
如果您确实想包含它们,请将其排除在外,并用或替换为 GNU 的限定符。除非您添加或选项,否则它本身会在符号链接解析之前报告类型。zsh
.
.
-.
zsh
-type
-xtype
find
ls -l
-L
-H