Pruebas condicionales para la existencia de archivos y tipos de archivos específicos en zsh

Pruebas condicionales para la existencia de archivos y tipos de archivos específicos en zsh

Quiero verificar en el directorio actual la existencia de archivos con extensiones de abc, bako tmp,oun archivo llamado tmpout.wrk. No puedo hacer que esto (eventualmente parte de una función) funcione en zsh. Se ejecuta, pero no lo detecta correctamente.

if [[ -f *.(abc|bak|tmp) || -f tmpout.wrk ]]; then 
    echo 'true'; 
else 
    echo 'false'; 
fi

Respuesta1

Para probar que el globo devuelve al menos un archivo, puedes hacer:

if ()(($#)) (*.(abc|bak|tmp)|tmpout.wrk)(NY1); then
  echo true
else
  echo false
fi

Para comprobar que al menos uno de ellos es un archivo normal después de la resolución del enlace simbólico, agregue el -. calificador global:

if ()(($#)) (*.(abc|bak|tmp)|tmpout.wrk)(NY1-.); then
  echo true
else
  echo false
fi
  • ()(($#))Es una función anónima a la que le pasamos el resultado de los globos. El cuerpo de esa función ( (($#))) simplemente prueba que el número de argumentos sea distinto de cero.

  • Ncuando se activa un calificador global nullglobpara ese global (hace que el global se expanda a nada cuando no coincide con ningún archivo)

  • Y1limita la expansión a como máximo un archivo. Es una optimización del rendimiento.

  • -hace que se considere el próximo clasificado globaldespuésresolución de enlace simbólico.

  • .considera solo archivos normales (por lo que aquí los archivos normales o enlaces simbólicos eventualmente se resuelven en un archivo normal, como [ -f file ]lo hace el comando).

Respuesta2

TL;DR

set -o extendedglob
if [[ -n *.(abc|bak|tmp)(#qN) || -f tmpout.wrk ]]; then

De lo contrario, mediante algunas pruebas,

% [[ -f /etc/passwd ]] && echo yea
yea
% echo /etc/passw?
/etc/passwd
% [[ -f /etc/passw? ]] && echo yea
% 

Bien, ¿qué está zshhaciendo aquí?

% set -x
% [[ -f /etc/passw? ]] && echo yes
+zsh:13> [[ -f '/etc/passw?' ]]
% 

Esas comillas simples seguro que no van a incluir nada. Busquemos [[en man zshall... y luego busquemos en CONDITIONAL EXPRESSIONS... ah, aquí hay algo sobre la generación de nombres de archivos:

   Filename  generation is not performed on any form of argument to condi-
   tions.  However, it can be forced in any case where normal shell expan-
   sion  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 [ or test builtin  commands
   then  globbing  occurs instead as part of normal command line expansion
   before the condition is evaluated.  In this case it may generate multi-
   ple 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 qual-
   ifier  N  ensures  that the expression is empty if there is no matching
   file.

Entonces, con esto en mente,

% [[ -f /etc/passw?(#q) ]] && echo yes
+zsh:14> [[ -f /etc/passwd ]]
+zsh:14> echo yes
yes
% exec zsh -l

Y a su caso, contabilizando el caso en el que puede que no existan expedientes:

% mkdir dir
% cd dir
% touch blah.foo
% [[ -f *.(foo|bar|baz)(#q) ]] && echo yea
yea
% rm blah.foo
% [[ -f *.(foo|bar|baz)(#q) ]] && echo yea
zsh: no matches found: *.(foo|bar|baz)(#q)
% [[ -f *.(foo|bar|baz)(#qN) ]] && echo yea
% touch a.foo b.foo
% [[ -f *.(foo|bar|baz)(#qN) ]] && echo yea
% [[ -n *.(foo|bar|baz)(#qN) ]] && echo yea
yea
% 

(aunque con -nsolo verificamos que los globos coincidan, no que los archivos correspondientes sean archivos normales).

información relacionada