zsh의 특정 파일 및 파일 유형 존재에 대한 조건부 테스트

zsh의 특정 파일 및 파일 유형 존재에 대한 조건부 테스트

abc현재 디렉토리에 , bak또는 확장자를 가진 파일이 있는지 확인하고 싶습니다 tmp.또는. tmpout.wrk​zsh에서 작동하도록 이 기능(결국 함수의 일부)을 얻을 수 없습니다. 실행되지만 제대로 감지하지 못합니다.

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

답변1

glob이 최소한 하나의 파일을 반환하는지 테스트하려면 다음을 수행할 수 있습니다.

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

심볼릭 링크 확인 후 그 중 적어도 하나가 일반 파일인지 확인하려면 -. glob 한정자를 추가하세요.

if ()(($#)) (*.(abc|bak|tmp)|tmpout.wrk)(NY1-.); then
  echo true
else
  echo false
fi
  • ()(($#))glob의 결과를 전달하는 익명 함수입니다. 해당 함수의 본문( (($#)))은 인수의 수가 0이 아닌지 테스트합니다.

  • N해당 glob에 대해 glob 한정자가 켜집니다 nullglob(파일과 일치하지 않으면 glob을 아무것도 확장하지 않음).

  • Y1확장을 최대 하나의 파일로 제한합니다. 성능 최적화입니다.

  • -다음 glob 한정자를 고려하게 만듭니다.~ 후에심볼릭 링크 해결.

  • .일반 파일만 고려합니다(따라서 여기서는 명령처럼 일반 파일이나 심볼릭 링크가 결국 일반 파일로 확인됩니다 [ -f file ]).

답변2

TL;DR

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

그렇지 않으면 일부 테스트를 통해

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

응, zsh여기서 뭐하는 거야?

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

작은 따옴표는 확실히 아무 것도 나오지 않을 것입니다. ... [[에서 검색한 man zshall다음 ...에서 검색해 보겠습니다 CONDITIONAL EXPRESSIONS. 아 여기 파일 이름 생성에 대한 내용이 있습니다.

   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.

따라서 이를 염두에 두고,

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

그리고 귀하의 경우에는 파일이 없을 수 있는 경우를 설명합니다.

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

(그러나 -n우리는 glob이 일치하는지만 확인하고 해당 파일이 일반 파일인지는 확인하지 않습니다).

관련 정보