Shell-Script

測試是否存在與模式匹配的文件以執行腳本

  • April 9, 2021

我正在嘗試編寫一個if語句來測試是否有任何文件與某個模式匹配。如果目錄中有文本文件,它應該執行給定的腳本。

我的程式碼目前:

if [ -f /*.txt ]; then ./script fi

請給出一些想法;如果目錄中有一個,我只想執行腳本.txt

[ -f /*.txt ]

僅當存在一個/(且只有一個)名稱以結尾的非隱藏文件.txt並且該文件是正常文件或指向正常文件的符號連結時才會返回 true 。

這是因為萬用字元在傳遞給命令之前由 shell 擴展(此處[)。

因此,如果有一個/a.txtand /b.txt[將傳遞 5 個參數:[-f/a.txt和。然後會抱怨給出了太多的論點。/b.txt``]``[``-f

如果要檢查*.txt模式是否擴展為至少一個非隱藏文件(正常或非隱藏文件),請在bashshell 中:

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 nullglobbash特定的(shopt是,nullglob實際上來自),但是像, , ,之類的zshshell具有等價的語句。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

(如果您想在符號連結解析之前進行測試,請刪除-,即無論符號連結是否指向正常文件,都將其視為非正常文件)。

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