Find

按名稱查找文件 glob 模式或正則表達式,但允許在開頭完全匹配,在結尾只允許某些字元

  • June 19, 2021

我正在嘗試匹配一些共享基本名稱但在末尾附加大小資訊find . -name 'Name*'以匹配文件的圖像文件,例如:

Name.jpg
Name@2x.jpg
Name-180x101.jpg
Name-180x101@2x.jpg

但是我的 glob 模式也匹配:

NameLonger.jpg
NameLonger@2x.jpg
NameLonger-180x101.jpg
NameLonger-180x101@2x.jpg

第二組是不希望的。

如何調整我的find命令以擊中第一組但忽略第二組?是否可以使用 glob 模式,還是需要正則表達式?

注意:對於這種情況,尺寸資訊 (-180x101) 始終是“-”,然後是任意數量的數字,然後是“x”,然後是任意數量的數字。如果文件包含“@​​2x”,則它始終位於末尾。

注意:它還必須命中純文件,例如:Name.jpg.

提前致謝。

使用zsh, 具體說明您想要的文件名格式:

print -rC1 -- **/Name(-<->x<->|)(@<->x|).jpg(DN)
  • print -rC1:柱上print r的 aw1 C
  • **/: 遞歸萬用字元
  • (a|b): 交替,(x|)就像 ERE(x)?
  • <x-y>: 表示整數 x 到 y 的十進制數字<->序列,表示任何數字的數字序列。
  • D: dotglob: 也可以查看隱藏目錄find
  • N: nullglob: 如果沒有匹配,不要抱怨,而是擴展為空。

一個 GNUfind等效項(沒有對文件進行排序,並且./每個路徑都帶有前綴):

LC_ALL=C find . -regextype posix-extended -regex \
 '.*/Name(-[0-9]+x[0-9]+)?(@[0-9]+x)?\.jpg'

(使用 BSD find,使用find -E .代替find . -regextype posix-extended

使用標準find,也許:

find . -name '.*/Name[-@.]*'

如果您只需要 exclude 就足夠了NameLonger

簡單的萬用字元模式沒有+, ?or|運算符的等效項。可以用多個ANDed 和 ORed 一起做等效的事情(比如接受-name但 拒絕、、、等) ,但這將非常麻煩,因為您需要數百個來處理所有情況。! -name``Name-*x*.jpg``Name-*[!0-9]*x*[!0-9]*.jpg``Name-x*``Name-*x.jpg

可以告訴該fnmatch()函式的GNU libc實現(由可以被告知使用它們。find -name``FNM_EXTMATCH``+(...)``?(...)``zsh -o kshglob``bash -O extglob``find

POSIXly,您可以訴諸awk完善匹配:

LC_ALL=C find . -name 'Name*' -exec awk '
 BEGIN {
   for (i = 1; i < ARGC; i++)
     if (ARGV[i] ~ "/Name(-[0-9]+x[0-9]+)?(@[0-9]+x)?\\.jpg$")
       print ARGV[i]
 }' {} +

(請記住,如果某些文件的路徑太長而無法放入命令行,則它可能會失敗。並非所有find實現都能夠找到比任何方法都長的路徑文件PATH_MAX)。

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