尋找在同一 CWD 中使用 regexp,但不能從另一個目錄使用

尋找在同一 CWD 中使用 regexp,但不能從另一個目錄使用

我有一個 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]匹配的內容不是隨機的,也不隨區域設定的變化而變化,例如 in find,並且匹配我認為您想要匹配的字符,並且僅匹配它們。在 中find,您需要[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]獲得同等的東西。
  • 即使$directory是目錄的符號連結它也可以工作(儘管您可以為此添加-H選項)。find
  • 即使檔案路徑(在本例中為 的內容$directory)包含在當前語言環境中不形成有效字元的位元組序列(find' -regexs.*無法匹配這些位元組,因為.僅匹配有效字元),它也可以工作。
  • 您可以直接使用它(作為命令的參數、循環遍歷等等),而不是列印該清單。
  • 您還可以使用諸如(<0-255>~????*)匹配 0 到 255 之間不超過 3 位數字的十進制數字或(<0-255>~0?*)不帶前導 0 的數字之類的內容,zshglob 是極少數支援數字匹配範圍的模式匹配 API 之一。

相關內容