我想如何显示没有特定文件的文件夹。但令人担忧的是,文件名称相同但大小写不同。
案例研究:在工具目录中,有包含readme
/README
文件的子目录,其中一些没有。例如
/toola/readme
/toolb/README
/toolc/ (does not have readme file)
Run Code Online (Sandbox Code Playgroud)
我希望 find 命令使用此命令仅显示 toolc 文件夹。
find . -maxdepth 2 ! -name '*readme*' -o ! -name '*README*' | awk -F "/" '{print $$2}' | uniq
Run Code Online (Sandbox Code Playgroud)
但它不起作用。它显示所有文件,因为toola
不具备README
和toolb
不具备readme
您不能用于find
查找不存在的文件。但是,您可以使用find
查找目录,然后测试给定的文件名是否存在于这些目录中。
当使用find
查找目录,请确保您使用-type d
。然后测试每个找到的目录中的文件README
和readme
.
假设某些顶级目录具有以下目录层次结构projects
:
projects/
|-- toola
| |-- doc
| |-- readme
| `-- src
|-- toolb
| |-- doc
| `-- src
|-- toolc
| |-- README
| |-- doc
| `-- src
`-- toold
|-- doc
`-- src
Run Code Online (Sandbox Code Playgroud)
使用find
直接找到的目录下projects
不包含一个README
或readme
文件:
$ find projects -mindepth 1 -maxdepth 1 -type d \
! -exec test -f {}/README ';' \
! -exec test -f {}/readme ';' -print
projects/toolb
projects/toold
Run Code Online (Sandbox Code Playgroud)
在这里,我们找到直接位于下面的任何目录projects
,然后使用该test
实用程序来确定找到的目录中的哪个不包含这两个文件中的任何一个。
这完全相当于
find projects -mindepth 1 -maxdepth 1 -type d \
-exec [ ! -f {}/README ] ';' \
-exec [ ! -f {}/readme ] ';' -print
Run Code Online (Sandbox Code Playgroud)
上述的另一种表述:
find projects -mindepth 1 -maxdepth 1 -type d -exec sh -c '
for pathname do
if [ ! -f "$pathname/README" ] &&
[ ! -f "$pathname/readme" ]; then
printf "%s\n" "$pathname"
fi
done' sh {} +
Run Code Online (Sandbox Code Playgroud)
在这里,我们让一个小的内嵌 shell 脚本对这两个文件进行实际测试,并打印不包含其中任何一个的目录的路径名。该find
实用程序的作用类似于目录路径名的“路径名生成器”,以便内嵌脚本进行迭代。
其实如果目录结构是这样的话,我们可能会选择根本不用find
:
for pathname in projects/*/; do
if [ ! -f "$pathname/README" ] &&
[ ! -f "$pathname/readme" ]; then
printf '%s\n' "$pathname"
fi
done
Run Code Online (Sandbox Code Playgroud)
请注意模式中的尾部斜线projects/*/
。正是这一点使模式只匹配目录(或目录的符号链接)。
这样做和使用之间的区别在于find
,在上述 shell 循环中,我们将排除隐藏的目录project
,并将包含指向目录的符号链接。
在所有情况下,我们遍历目录的路径名,并测试两个文件名是否不存在。
唯一需要注意的是,该-f
测试也适用于到常规文件的符号链接。
有关的: