Bash

glob 變數必須用雙引號括起來

  • June 19, 2020

此連結:在我的情況下,引號內的萬用字元 不能解決問題。

文件“a.sh”包含:

file="path with wildcard*"

文件“b.sh”包含:

. a.sh
[ -f "$file" ] && echo ok

因為

"$file"

不擴展萬用字元,而是

$file

展開萬用字元,但出現錯誤:“應使用二元運算符”

我該如何解決這個難題?不能將萬用字元從雙引號中取出。

編輯:

我想從萬用字元中實現一個匹配。如果有更多匹配,則條件必須返回 false,在任何情況下都必須返回錯誤。

如果您想將由儲存在變數 in 中的 glob 模式擴展產生的文件列表儲存在數組bash中,那將是:

pattern='path with wildcard*'

IFS= # disable splitting

shopt -s nullglob # make globs that don't match any file expand to nothing
                 # instead of the unexpanded pattern.

files=($pattern) # here using split+glob (unquoted expansion in list context)
                # with the splitting disabled above.

或者直接分配$files數組而不使用$pattern標量變數:

shopt -s nullglob # make globs that don't match any file expand to nothing
                 # instead of the unexpanded pattern.

files=('path with wildcard'*)

然後您可以測試該列表是否為空:

if [ "${#files[@]}" -gt 0 ]; then
 echo it did find some files
fi

如果你想檢查,在這些文件中,至少有一個是正常文件(在符號連結解析之後),你可以這樣做:

has_regular_files() {
 local file
 for file do
   [ -f "$file" ] && return
 done
 false
}

if has_regular_files "${files[@]}"; then
 echo there was at least one regular file in the list
fi

要檢查它是否僅匹配一個文件並且該文件是正常文件:

if [ "${#files[@]}" -eq 1 ] && [ -f "${files[0]}" ]; then
 echo one and only one file matches and it is regular.
fi

要檢查它是否匹配至少一個正常文件並且所有匹配的文件都是正常文件:

only_regular_files() {
 [ "$#" -gt 0 ] || return
 local file
 for file do
   [ -f "$file" ] || return
 done
}

if only_regular_files "${files[@]}"; then
 echo at least one regular file and all are regular.
fi

使用zshshell,您可以使用 glob 限定符按文件類型進行匹配:

if ()(($#)) $~pattern(N-.); then
 print at least one regular file in the expansion of the pattern.
fi
  • bash,不同的是,zsh在未引用的參數擴展時不會執行隱式 split+glob 。在這裡,我們要求使用$~pattern.
  • 我們附加(N-.)glob 限定符,N以便nullglob如果 glob 不匹配任何文件,它會擴展為無.以僅測試正常文件(排除任何其他類型的文件),-以便在符號連結解析之後完成該測試,因此它會還匹配作為正常文件的符號連結的文件(就像你想要的[ -f "$file" ]那樣)。
  • 該 glob 的擴展作為參數傳遞給匿名函式,() {body} args其中{body}is (($#))
  • ((expr))是一個 ksh 風格的算術表達式求值運算符,如果表達式求值為 0 以外的數字,則返回 true。這裡,表達式是$#,它是一個特殊參數,它擴展為位置參數的數量,在這種情況下是該匿名函式的參數,因此該全域擴展產生的文件數。

引用自:https://unix.stackexchange.com/questions/593324