2

I hate the find command, just want to get that out there. By far the worst designed CLI tool in linux land that I have used over many years.

Turns out, the following command will return nothing:

cd "$go_proj_path_root" && cd .. && find "$go_proj_path_root" -mindepth 1 -maxdepth 1 -type l -type d

it returns nothing because apparently -type l and -type d contradict each other? If I just use:

cd "$go_proj_path_root" && cd .. && find "$go_proj_path_root" -mindepth 1 -maxdepth 1 -type l 

then it will find the symlinks in the dir. Is there some way to find both dirs and symlinks with the same command? Truly awful, find! If I just wanted symlinks, then I would just use -type l..wtf.

2 Answers 2

2

Yes, -type l -type d means "if the file is a directory and a symbolic link". What you might want to try is \( -type l -o -type d \).

Note too that your cd is not neccesary (unless you're using it to verify that $go_proj_path_root is a directory that you have access to):

find "$go_proj_path_root" -mindepth 1 -maxdepth 1 \( -type l -o -type d \) -print

Alternatively, since you seem to only be interested in the files in a single directory:

shopt -s nullglob dotglob
for name in "$go_proj_path_root"/*; do
    if [ -d "$name" ] || [ -L "$name" ]; then
        printf '%s\n' "$name"
    fi
done

With the zsh shell:

print -rC1 -- $go_proj_path_root/*(ND/) $go_proj_path_root/*(ND@)

... where the glob qualifiers / and @ will cause the preceding globbing pattern to only match directories or symbolic links respectively, and ND has the same effects as setting the nullglob and dotglob shell options in bash (expand to nothing if no match and also match hidden names). The print -rC1 will print the resulting names in a single column (-r avoids interpreting backslash sequences).

1
  • Since -mindepth and -maxdepth are global parameters, there’s no need to protect the -o or use -print (but yes, it’s a good habit to get into). Mar 12, 2020 at 8:09
1

When you add criteria to find, it applies them all by default: so

find "$go_proj_path_root" -mindepth 1 -maxdepth 1 -type l -type d

is asking for files which are simultaneously links and directories.

You need to use “or”:

find "$go_proj_path_root" -mindepth 1 -maxdepth 1 -type l -o -type d

While it’s not necessary here, it’s a good idea to get into the habit of using parentheses around -o:

find "$go_proj_path_root" -mindepth 1 -maxdepth 1 \( -type l -o -type d \)

(escaped so they don’t mean anything to the shell).

1
  • this prob works, and so does my answer? only tested mine once
    – user393961
    Mar 12, 2020 at 8:07

You must log in to answer this question.