根据包含和排除特定文件列出Linux中的目录

时间:2017-01-17 22:17:46

标签: linux bash directory find

简短版本:

我正在尝试编写一个bash命令,该命令将根据某些文件的存在和/或不存在生成子目录列表。如果目录名称包含名为“Ready”的文件并且不包含名为“Complete”或“Failed”的文件,则该目录名称将包含在列表中。基于我在这里看到的例子,我一直在使用'find'命令,但是我对它没有足够的把握或一般的bash来使它工作。

find . -maxdepth 1 -name Ready | find -mindepth 1 -maxdepth 1 -type d '!' -exec test -e "{}/Complete" ';' -print | find -mindepth 1 -maxdepth 1 -type d '!' -exec test -e "{}/Failed" ';' -print

长版:

在我们的系统中,另一个组会删除由我们的某个应用程序处理的文件目录(“bundle”)。这些目录可以包含一个或多个零长度状态文件,这些文件指定捆绑包已准备好进行处理(“就绪”),或者应该被忽略,因为它已成功处理(“已完成”)或之前出现错误(“失败” “)。

系统的大部分都是购买的软件,我们开始开发一些自行开发的监控,管理和指标收集工具。我正在尝试编写一个脚本,它将在任何给定时间查看这些目录,并根据状态文件的存在与否来确定哪些已准备好进行处理,哪些将被忽略。

3 个答案:

答案 0 :(得分:1)

假设您正在使用bash 4或更高版本,我将跳过find并迭代递归的glob **/*/

shopt -s globstar nullglob
for d in **/*/; do
  [[ -e $d/Ready ]] || continue  # Skip directories without a Ready file
  [[ -e $d/Completed ]] && continue  # Skip directories with a Completed file
  [[ -e $d/Failed ]] && continue  # Skip directories with a Failed file
  print '%s\n' "$d"  # If you made it this far, print the directory name
done

这可以浓缩为

shopt -s globstar nullglob
for d in **/*/; do
  [[ -e $d/Ready && ! (-e $d/Completed || -e $d/Failed) ]] && printf '%s\n' "$d"
done

您也可以使用glob来标识包含Ready的目录:

for f in **/*/Ready; do
  d=${f%Ready}
  [[ -e $d/Completed || -e $d/Failed ]] || printf '%s\n' "$d"
done

答案 1 :(得分:0)

您可以使用find选项not匹配某些名称:

find . -maxdepth 2 -path "*Ready*" ! -name "Failed" -a ! \
-name "Complete" -exec bash -c 'echo "$0"' {} \;

在嵌套目录-path中,只能找到“Ready”目录中不包含(!)“Failed”或“Complete”的文件。例如:

$ ls
Complete Failed   Ready    outdir   sub1     sub2     sub3 

$ cd Ready ; ls
Complete Failed   Ready    somefile

从父目录使用上面的find命令将产生:

./Ready
./Ready/Ready
./Ready/somefile

如果您将-path切换为-name,您将获得:

./Ready
./Ready/Ready

find是一款功能强大的实用工具,可以根据搜索范围内的任何需求进行调整。

答案 2 :(得分:0)

这是一件简单的事。

find命令开始,找到用作触发器的文件。把它管成一个" grep"这将摆脱文件名,排序,消除重复,如:

find . -type f -name Ready -o -name Completed -o -name Failed | grep -o "^.*/" | sort | uniq

-maxdepth 2 -mindepth之前添加-type f 2,将深度限制为1级。