Bash
glob 變數必須用雙引號括起來
此連結:在我的情況下,引號內的萬用字元 不能解決問題。
文件“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
使用
zsh
shell,您可以使用 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。這裡,表達式是$#
,它是一個特殊參數,它擴展為位置參數的數量,在這種情況下是該匿名函式的參數,因此該全域擴展產生的文件數。