0

You likely don't need find if you're using Zsh. Zsh globs can do most of what find can do through its recursive globbing, extended globs and glob qualifiers. For example, your find ./test-folder -type f -name '*.txt' is just ./test-folder/**/*.txt(D.) D to include hidden files to match find's default behaviour. You may not need it, . for -type f.

— Stéphane Chazelas, here on unix.stackexchange

The test-folder contains 4 files: a.txt, b.txt, c.txt, and x.jpg.

When I execute ./test-folder/**/*.txt(D.), it returns

zsh: permission denied: ./test-folder/a.txt

What does permission denied mean here? And why it don't find b.txt and c.txt?

zsh 5.9 (x86_64-apple-darwin23.0)

4
  • 2
    You probably want something like print -r ./test-folder/**/*.txt(D.) otherwise the shell tries to execute the first match as a command, with the remaining matches as arguments. Commented May 12 at 20:07
  • @steeldriver This works, thanks. Though I'm not sure I do understand which advantages over find globs provide. There are almost the same number of characters to type.
    – jsx97
    Commented May 12 at 20:12
  • @steeldriver Could you explain what does -p is used for here? man print returns No manual entry for print.
    – jsx97
    Commented May 16 at 11:02
  • In this context print is a shell builtin - you should be able to find a list of its options under man zshbuiltins or online here Commented May 16 at 11:37

1 Answer 1

1

The reason you get "permission denied" is because you tried to run the file ./test-folder/a.txt which does not have execute permission and probably is not executable even if it did. As suggested in comments, you need to put a command in front of this to print or operate on the file instead of execute it.

As to advantages of zsh glob over running find, it can greatly simplify command lines that need to do very simple file searches when combined with other commands. However, it lacks the flexibility of the find command, and does not fix the case where you can't fit all the matched filenames on the command line.

It doesn't replace find, its just a shortcut, and it's not meant to be used stand alone as your example attempts.

If all you wanted was a list of files, it might be a toss up if you use zsh glob or find. But if you combine it with another command, for simple searches zsh glob is almost always shorter.

For example, if you wanted to view every txt file in a small directory tree, this might be useful:

less test-folder/**/*.txt

But if you happened to have a directory that ended in .txt this might make less unhappy, so you could filter that by instead using

less test-folder/**/*.txt(.)

which is certainly shorter than

less $(find test-folder -type f -name '*.txt')

and doesn't do quite the same thing as

find test-folder -type f -name '*.txt' -exec less {} +

Changing the zsh glob ending from *.txt(.) to *.txt(D.) would allow it to also match the exact filename .txt which would otherwise be skipped.

3
  • 1
    Re: "However, it lacks the flexibility of the find command". There are a few things find can do that are harder to do in zsh globs such as pruning directories based on criteria other than name or avoid crossing filesystem boundaries (-xdev), but there are also a number of zsh glob features that are hard to achieve in find (even GNU find), like the file<1-200>.txt, the *(+function), the selective case insensitivity, the ordering... All in all, I wouldn't say find is more flexible. Commented May 13 at 7:21
  • 1
    Worth noting that less $(find test-folder -type f -name '*.txt') is wrong (and dangerous!) anyway (even if less so than in other POSIX-like shells) as it fails if file paths contain space, tab or newline characters (assuming the default value of $IFS). You'd need IFS=$'\0' and use less $(find -H test-folder ... -print0 | sort -z) (with GNUisms) to have something equivalent. Commented May 13 at 7:25
  • 1
    Without D, **/*.txt(.) would also exclude .foo.txt, .git/file.txt, that is all hidden files, not just .txt. Though in general, that's what you want. Excluding hidden files in find is quite painful and in some systems cannot be done reliably in multibyte locales. Commented May 13 at 7:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .