Bash check if file exists with double control and wildcards

I am writing a Bash script and should check if a file exists that looks like *.$1.*.ext. I can do this very easily with the POSIX test, since it [ -f *.$1.*.ext ]returns true, but using a double bracket [[ -f *.$1.*.ext ]]does not work.

This is just to satisfy curiosity, as I cannot believe that advanced testing simply cannot determine if a file exists. I know what I can use [[ `ls *.$1.*.ext` ]], but it will match if there is more than one match. Maybe I could pass it on wcor something like that, but that seems awkward.

Is there an easy way to use double brackets to check for a file using wildcards?

EDIT: I see that [[ -f `ls -U *.$1.*.ext` ]]works, but I would prefer not to call ls.

+4
source share
2 answers

Neither [ -f ... ](nor [[ -f ... ]]other file verification operators) are designed to work with templates (aka globs, wildcard expression) . They always interpret their operand as a literal file name. [1]

A simple trick is to check whether the template (glob) matches exactly one file , use a helper function :

existsExactlyOne() { [[ $# -eq 1 && -f $1 ]]; }

if existsExactlyOne *."$1".*.ext; then # ....

If you are just wondering if there are any matches, i.e. one or more , the function is even simpler:

exists() { [[ -f $1 ]]; }

If you want to avoid a function , it becomes more complex :

. , , ( .)

if [[ $(shopt -s nullglob; set -- *."$1".*.ext; echo $#) -eq 1 ]]; then # ...
  • ($(...)) :
    • shopt -s nullglob bash ,
    • set -- ... ($1, $2,...) , .
    • echo $# , ;
  • ( stdout ) -eq, () 1.

, , , .. , -eq -ge.


[1]
@Etan Reisinger , [ ... ] ( ) , -f ( ).

bash [[ ... ]], - (.. ).

, ( ) :

  • [[ ... ]] : .
  • [ ... ] , .
    • :
      • , nullglob ( ), , nullglob , true, -f, - , ( )).
    • : [ ... ] , , .
+8

bash , bash , :

file=(*.ext)
[[ -f "$file" ]] && echo "yes, ${#file[@]} matching files"

, : , . , -f .

, , , , , , - . , .

+4

Source: https://habr.com/ru/post/1547455/


All Articles