bashfindhidden-files

Find all directories that contain only hidden files and/or hidden directories


Issue

Visual Explanation

+--- 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

Desired Output

Attempts


Solution

  • Parsing find's output is not a good idea; -exec exists, and sh can do the filtering without breaking anything.

    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 {} +
    

    You can adjust the depth using whatever extension your find provides for it.