我有一個 find 命令,我想從任意目錄發出它,並用一個$directory
變數代替.
當前工作目錄的點。
有效的是這個
- 實施例1
find $directory -maxdepth 1 -type d -name "test*"
這給了我一些結果。
這也有效
- 實施例2
find . -maxdepth 1 -type d -regextype posix-extended -regex "^./[a-zA-Z0-9]+([-_]?[a-zA-Z0-9]+)*-[0-9]{1,3}(.[0-9]{1,3}){,3}\$"
但是,使用 a$directory
則不起作用。請注意,我刪除了./
正規表示式開頭的 。
- 實施例3
find $directory -maxdepth 1 -type d -regextype posix-extended -regex "^[a-zA-Z0-9]+([-_]?[a-zA-Z0-9]+)*-[0-9]{1,3}(.[0-9]{1,3}){,3}\$"
為什麼會這樣呢?
謝謝
答案1
-regex
(非標準),就像-path
檔案完整路徑上的標準匹配一樣。這些路徑以 的內容開頭,$directory
後面跟著 找到的目錄和檔案find
。因此,如果$directory
是/some/dir
,-regex
將與正則表達式匹配/some/dir/file-discovered-by-find
,並且永遠不會在這裡匹配,因為第一個字元是 a /
,而不是 alnum。
在第一種情況下,您的正規表示式以^./
(應該^\./
是.
正規表示式運算符,或者就像\./
GNU中^
暗示的那樣)開頭,因為有。find
-regex
$directory
.
您需要對 執行類似的操作$directory
,請記住$directory
( ^$*()+[]?.\
...) 中的所有正規表示式運算子都需要轉義。但在這裡你不妨這樣做:
find "$directory" -maxdepth 1 -type d -regextype posix-extended \
-regex '.*/[[:alnum:]]+([-_][[:alnum:]]+)*-[[:digit:]]{1,3}(\.[[:digit:]]{1,3}){0,3}'
(我還替換了.
,\.
因為我懷疑您想要匹配文字.
而不僅僅是任何字符,並刪除了?
此處不需要的)。
也就是說,讓您的模式(這裡保證不包含/
)在任何匹配的內容之後/
(並且一直到文件路徑的末尾($
也暗示如此)匹配,而不是在匹配的內容之後$directory
。
使用zsh -o extendglob
,您可以執行以下操作:
set -o extendedglob
w=[0-9a-zA-Z] d=[0-9]
print -rC1 -- $directory/$~w##([-_]$~w##)#-$~d(#c1,3)(.$~d(#c1,3))(#c0,3)(#q/)
與 GNUfind
相比,它有幾個優點:
- 即使在非 GNU 系統上也可以工作(消除對 GNU 的依賴
find
) - 即使
$directory
開始也有效-
- 給你一個排序列表
- in 中
zsh
,[a-zA-Z0-9]
匹配的內容不是隨機的,也不隨區域設定的變化而變化,例如 infind
,並且匹配我認為您想要匹配的字符,並且僅匹配它們。在 中find
,您需要[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]
獲得同等的東西。 - 即使
$directory
是目錄的符號連結它也可以工作(儘管您可以為此添加-H
選項)。find
- 即使檔案路徑(在本例中為 的內容
$directory
)包含在當前語言環境中不形成有效字元的位元組序列(find
'-regex
s.*
無法匹配這些位元組,因為.
僅匹配有效字元),它也可以工作。 - 您可以直接使用它(作為命令的參數、循環遍歷等等),而不是列印該清單。
- 您還可以使用諸如
(<0-255>~????*)
匹配 0 到 255 之間不超過 3 位數字的十進制數字或(<0-255>~0?*)
不帶前導 0 的數字之類的內容,zsh
glob 是極少數支援數字匹配範圍的模式匹配 API 之一。