查找仅包含隐藏文件和/或隐藏目录的所有目录

Posted

技术标签:

【中文标题】查找仅包含隐藏文件和/或隐藏目录的所有目录【英文标题】:Find all directories that contain only hidden files and/or hidden directories 【发布时间】:2021-08-26 21:09:41 【问题描述】:

问题

我一直在努力编写一个 Bash 命令,该命令能够递归搜索一个目录,然后返回包含 exclusively hidden 的每个子目录的路径(直到某个最大深度)文件和/或隐藏目录。

视觉解释

考虑以下文件系统摘录:
+--- Root_Dir
|   +--- Dir_A
|   |   +--- abc.txt
|   |   +--- 123.txt
|   |   +--- .hiddenfile
|   |   +--- .hidden_dir
|   |   |   +--- normal_sub_file_1.txt
|   |   |   +--- .hidden_sub_file_1.txt
|   |     
|   +--- Dir_B
|   |   +--- abc.txt
|   |   +--- .hidden_dir
|   |   |   +--- normal_sub_file_2.txt
|   |   |   +--- .hidden_sub_file_2.txt
|   |    
|   +--- Dir_C
|   |   +--- 123.txt
|   |   +--- program.c
|   |   +--- a.out
|   |   +--- .hiddenfile
|   |   
|   +--- Dir_D
|   |   +--- .hiddenfile
|   |   +--- .another_hiddenfile
|   |     
|   +--- Dir_E
|   |   +--- .hiddenfile
|   |   +--- .hidden_dir
|   |   |   +--- normal_sub_file_3.txt   # This is OK because its within a hidden directory, aka won't be checked
|   |   |   +--- .hidden_sub_file_3.txt
|   | 
|   +--- Dir_F
|   |   +--- .hidden_dir
|   |   |   +--- normal_sub_file_4.txt
|   |   |   +--- .hidden_sub_file_4.txt

期望的输出

我正在寻找的命令将输出
./Root_Dir/Dir_D
./Root_Dir/Dir_E
./Root_Dir/Dir_F
Dir_D 因为它只包含隐藏文件。 Dir_E 因为它只包含我正在搜索的级别的隐藏文件和隐藏目录。 Dir_F 因为它只包含我正在搜索的级别的隐藏目录。

尝试

我已尝试使用find 命令来获得我正在寻找的结果,但我似乎无法弄清楚我需要将输出传输到哪些其他命令或我应该使用哪些其他选项。 我认为可行的命令如下所示:
$ find ./Root_Dir -mindepth 2 -maxdepth 2 -type d -name "*." -type -f -name "*." | command to see if these are the only files in that directory  

【问题讨论】:

什么都不包含的目录呢?解决方案应该返回什么?还是不考虑这种情况? 每个目录包含 2 个目录:...,它们隐藏,那么您的搜索将返回整个树。 【参考方案1】:

解析find的输出不是一个好主意; -exec 存在,sh 可以在不破坏任何东西的情况下进行过滤。

find . -type d -exec sh -c '
for d; do
  for f in "$d"/*; do
    test -e "$f" &&
      continue 2
  done
  for f in "$d"/.[!.]* "$d"/..?*; do
    if test -e "$f"; then
      printf %s\\n "$d"
      break
    fi
  done
done' sh  +

您可以使用 find 为其提供的任何扩展来调整深度。

【讨论】:

【参考方案2】:

假设这个结构,你不需要find。 根据需要调整您的模式。

for d in $ROOT_DIR/Dir_?/; do
  lst=( $d* );  [[ -e "$lst[0]" ]] && continue # normal files, skip
  lst=( $d.* ); [[ -e "$lst[2]" ]] || continue # NO hidden, so skip
  echo "$d"
done

我在/tmp 目录中重建了您的文件结构并将其保存为tst,所以

$: ROOT_DIR=/tmp ./tst
/tmp/Dir_D/
/tmp/Dir_E/
/tmp/Dir_F/

请注意,隐藏文件的确认使用"$lst[2]",因为前两个将始终是...,这不算。

您可能会使用for d in $ROOT_DIR/*/。 我怀疑这对你有用。 (最小深度=2,最大深度=2)

如果您需要更深的子目录(mindepth=3,maxdepth=3),您可以添加一个级别 -

for d in $ROOT_DIR/*/*/

和/或两者(最小深度=2,最大深度=3)

for d in $ROOT_DIR/*/ $ROOT_DIR/*/*/

或者如果您想要最小深度/最大深度,

shopt -s globstar
for d in $ROOT_DIR/**/

【讨论】:

【参考方案3】:

如果您的文件名不包含换行符,这将起作用。

find -name '.*' | awk -F/ -v OFS=/ ' --NF  !a[$0]++'

学习 awk:https://www.gnu.org/software/gawk/manual/gawk.html

【讨论】:

以上是关于查找仅包含隐藏文件和/或隐藏目录的所有目录的主要内容,如果未能解决你的问题,请参考以下文章

Jenkinsfile,“查找”,忽略一些隐藏目录和其他文件夹

检查文件或目录是不是隐藏

Linux--常用命令

文件或目录权限chmod,更改所有者和所属组chown ,umask的使用 ,隐藏权限的使用 lsattr,chattr

ls -a 显示所有文件,包括隐藏文件。

文件和目录权限更改所有者和所属组umask隐藏权限