測試是否存在與模式匹配的文件以執行腳本
我正在嘗試編寫一個
if
語句來測試是否有任何文件與某個模式匹配。如果目錄中有文本文件,它應該執行給定的腳本。我的程式碼目前:
if [ -f /*.txt ]; then ./script fi
請給出一些想法;如果目錄中有一個,我只想執行腳本
.txt
。
[ -f /*.txt ]
僅當存在一個
/
(且只有一個)名稱以結尾的非隱藏文件.txt
並且該文件是正常文件或指向正常文件的符號連結時才會返回 true 。這是因為萬用字元在傳遞給命令之前由 shell 擴展(此處
[
)。因此,如果有一個
/a.txt
and/b.txt
,[
將傳遞 5 個參數:[
、-f
、/a.txt
和。然後會抱怨給出了太多的論點。/b.txt``]``[``-f
如果要檢查
*.txt
模式是否擴展為至少一個非隱藏文件(正常或非隱藏文件),請在bash
shell 中:shopt -s nullglob set -- *.txt if [ "$#" -gt 0 ]; then ./script "$@" # call script with that list of files. fi # Or with bash arrays so you can keep the arguments: files=( *.txt ) # apply C-style boolean on member count (( ${#files[@]} )) && ./script "${files[@]}"
shopt -s nullglob
是bash
特定的(shopt
是,nullglob
實際上來自),但是像, , ,之類的zsh
shell具有等價的語句。ksh93``zsh``yash``tcsh
使用,可以使用匿名函式和(for ) 和(在第一次查找後停止) glob 限定符來編寫是否存在匹配模式的文件
zsh
的測試:N``nullglob``Y1
if ()(($#)) *.txt(NY1); then do-something fi
請注意,那些通過讀取目錄的內容來找到這些文件的人,它根本不會嘗試訪問這些文件,這使得它比呼叫類似命令的解決方案更有效,
ls
或者stat
在由 shell 計算的文件列表上。標準
sh
等價物是:set -- [*].txt *.txt case "$1$2" in ('[*].txt*.txt') ;; (*) shift; script "$@" esac
問題在於,對於 Bourne 或 POSIX shell,如果一個模式不匹配,它就會擴展到自身。所以如果
*.txt
展開為*.txt
,你不知道是因為.txt
目錄中沒有文件還是因為有一個文件名為*.txt
. 使用[*].txt *.txt
允許區分兩者。現在,如果您要檢查是否
*.txt
匹配至少一個正常文件或符號連結到正常文件(就像您[ -f *.txt ]
建議的那樣),或者所有匹配的文件*.txt
都是正常文件(在符號連結解析之後),那是另一回事.與
zsh
:if ()(($#)) *.txt(NY1-.); then echo "there is at least one regular .txt file" fi if ()(($#)) *.txt(NY1^-.); then echo "there is at least one non-regular .txt files" fi
(如果您想在符號連結解析之前進行測試,請刪除
-
,即無論符號連結是否指向正常文件,都將其視為非正常文件)。