如何找到目录中不包含给定文件的所有子目录(仅向下 1 级)?
答案1
有几种方法可以实现这一点寻找。
方法 1 不太复杂,并且可以很好地处理奇怪的目录名(例如,包含换行符的目录名),但如果有很多目录,方法 2 应该更快。
方法 1
命令
find DIR -type d -mindepth 1 -maxdepth 1 -not -exec test -f {}/FILENAME \; \
-print | sort
怎么运行的
find DIR -type d -mindepth 1 -maxdepth 1
查找所有目录 (-type d
)目录,深度为 1。-not -exec test -f {}/FILENAME \;
当且仅当文件名为文件名在当前处理的目录中找不到({}
)。-print
将输出所需的目录名称。如果需要,
sort
将按字母顺序对输出进行排序。
方法 2
命令
( find DIR -type f -mindepth 2 -maxdepth 2 -name FILENAME -printf "%h\n" ; \
find DIR -type d -mindepth 1 -maxdepth 1 ) | sort | uniq -u
怎么运行的
find DIR -type f -mindepth 2 -maxdepth 2 -name FILENAME
查找所有名为 (-type f
) 的文件文件名在子目录中目录(深度为 1 的目录的文件深度为 2)。-print "%h\n"
打印包含以下文件的目录名称文件名,然后是换行符。find DIR -type d -mindepth 1 -maxdepth 1
列出所有目录 (-type d
)目录,深度为 1。sort
按字母顺序对输出进行排序(传输到 时必须对输出进行排序uniq
)。uniq -u
仅打印唯一的行。每个子目录目录至少被列出一次,但那些包含名为文件名被列出两次。
uniq -u
消除了后一种。
答案2
直接在 shell 脚本中:
for i in DIRECTORY/*/; do [ -f "$i/FILENAME" ] || basename "$i"; done
for i in DIRECTORY/*/
使用 shell 扩展安全地(奇怪的目录名不会有问题)给出特定目录的所有子目录。请注意,尾部的斜杠仅给出目录。[ -f "$i/FILENAME" ]
如果此迭代中指定的文件FILENAME
存在于目录中,则返回 true。||
如果第一个命令返回 false,即仅当文件确实存在时,操作员才会运行以下命令不是存在于目录中。basename "$i"
打印目录名称(如果未在其中找到文件名)。如果您想要完整路径而不仅仅是目录名称,请根据偏好替换basename
或echo
或readlink -f
其他内容。
如果你还想包含隐藏目录,请运行(在 Bash 中)
shopt -s dotglob
在命令之前。