I have a glob pattern PATTERN and would like to implement the following logic in Zsh:
if a file matching *PATTERN* exists, then
do this-and-that
end
Note that I don't need to know, which files actually match the pattern; only the fact that there is some file (or directory) is relevant.
I couldn't find a clever way to do this with an if
statement, so I implemented it using a "loop" which is executed at most once:
for f in *PATTERN*(N)
do
this-and-that
break
done
This works: If no entry matches PATTERN, the (N) causes an error message to be suppressed and the loop is skipped; otherwise, the loop body is executed once.
Question: Is there a way where I can achieve my goal with just a if
, no loop?
Yes, there is in zsh. (setopt extendedglob
required for the (#q…)
form glob qualifier notation.)
if [[ -n *PATTERN*(#qN) ]]; then
this-and-that
fi
There are some descriptions and a similar example in zsh's documents "CONDITIONAL EXPRESSIONS" and "Glob Qualifiers":
Filename generation is not performed on any form of argument to conditions. However, it can be forced in any case where normal shell expansion is valid and when the option
EXTENDED_GLOB
is in effect by using an explicit glob qualifier of the form(#q)
at the end of the string. A normal glob qualifier expression may appear between the ‘q
’ and the closing parenthesis; if none appears the expression has no effect beyond causing filename generation. The results of filename generation are joined together to form a single word, as with the results of other forms of expansion.This special use of filename generation is only available with the
[[
syntax. If the condition occurs within the[
ortest
builtin commands then globbing occurs instead as part of normal command line expansion before the condition is evaluated. In this case it may generate multiple words which are likely to confuse the syntax of the test command.For example,
[[ -n file*(#qN) ]]
produces status zero if and only if there is at least one file in the current directory beginning with the string ‘
file
’. The globbing qualifierN
ensures that the expression is empty if there is no matching file.--
zshmisc(1): CONDITIONAL EXPRESSIONS
--
If the option
EXTENDED_GLOB
is set, a different syntax for glob qualifiers is available, namely ‘(#qx)
’ wherex
is any of the same glob qualifiers used in the other format. The qualifiers must still appear at the end of the pattern. However, with this syntax multiple glob qualifiers may be chained together. They are treated as a logical AND of the individual sets of flags. Also, as the syntax is unambiguous, the expression will be treated as glob qualifiers just as long any parentheses contained within it are balanced; appearance of ‘|
’, ‘(
’ or ‘~
’ does not negate the effect. Note that qualifiers will be recognised in this form even if a bare glob qualifier exists at the end of the pattern, for example ‘*(#q*)(.)
’ will recognise executable regular files if both options are set; however, mixed syntax should probably be avoided for the sake of clarity. Note that within conditions using the ‘[[
’ form the presence of a parenthesised expression(#q...)
at the end of a string indicates that globbing should be performed; the expression may include glob qualifiers, but it is also valid if it is simply(#q)
. This does not apply to the right hand side of pattern match operators as the syntax already has special significance.--
zshexpn(1): Expansion, Filename Generation, Glob Qualifiers
one way you can do is, load the found files(filenames) in an array, and check the array length:
a=(*.txt)
echo ${#a}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With