Linux

查找包含數字的文件名

  • July 23, 2020

我想查找包含數字的文件名並將它們列出在一系列數字中。例如,在我的目錄中,我有:**

Ion_001_rawlib.bam
Ion_002_rawlib.bam
Ion_003_rawlib.bam
Ion_004_rawlib.bam
Ion_005_rawlib.bam
...
Ion_020_rawlib.bam

**

我只想列出從 003 到 005 的 Ion 文件名。我試圖做這樣的事情:

find -name '*Ion_*[3-5]*rawlib.bam'

但它不會產生預期的效果。你知道它是否可以執行嗎?謝謝。

使用zsh外殼,您可以執行以下操作:

print -rC1 Ion_<3-5>_rawlib.bam

Where<x-y>是一個 glob 運算符,它匹配給定範圍內的正整數的文本十進製表示(從xy,包括在內)。

遞歸:

print -rC1 -- **/Ion_<3-5>_rawlib.bam

(D)如果您還想在隱藏文件夾中查找這些文件,或者(N)如果您不想在沒有匹配文件時將其視為錯誤,請添加)。

使用find支持-regex謂詞的實現,您可以執行以下操作:

LC_ALL=C find . -regex '.*/Ion_0*[345]_rawlib\.bam'

*(匹配 0 或更多 ( ) 字節 ( .with LC_ALL=C) 後跟/Ion_0 或更多 ( *)的文件路徑,0後跟3,45字元之一rawlib.bam)。

在這裡,3..5 範圍相對容易,但對於 78..123 之類的範圍會變得更加痛苦(並且您會遇到兼容性問題,因為那裡支持使用不同格式的正則表達式的少數find實現-regex)。

標準find僅支持-name-path用於匹配文件名,它使用基本的 shell 萬用字元而不是正則表達式來完成,但萬用字元沒有*regexp 運算符的等效項(前面的原子的 0 個或多個),它的*運算符等效於 regexp .*(0 個或多個字元),因此Ion_*[3-5]_rawlib.bam將匹配 onIon_9994_rawlib.bam例如*匹配 on 999

然而,在這個簡單的情況下,您可以使用幾種模式和否定來完成,例如:

LC_ALL=C find . -name 'Ion_*[345]_rawlib.bam' \
             ! -name 'Ion_*[!0]*?_rawlib.bam'

非遞歸:

LC_ALL=C find . ! -name . -prune \
   -name 'Ion_*[345]_rawlib.bam' \
 ! -name 'Ion_*[!0]*?_rawlib.bam'

x要在名稱中的任何位置查找包含整數的十進製表示的文件y,您需要一個與該範圍匹配的模式(如zsh’s <x-y>),但還要確保該模式不被其他數字包圍。例如foo305.txt確實包含3,055, 所有這些都匹配<3-5>

zsh中,那將是:

print -rC1 -- (|*[^0-9])<3-5>(|[^0-9]*)

<3-5>(匹配 3、03、003…)之後是空字元或以非數字結尾的字元串,然後是空字元或以非數字開頭的字元串。

使用 BSD find

LC_ALL=C find -E . -regex '.*/([^/]*[^0-9])?0*[3-5]([^0-9][^/]*)?'

與 GNUfind相同,但替換-E .. -regextype posix-extended.

使用busybox find(儘管取決於它的編譯方式):

busybox find . -regex '.*/\([^/]*[^0-9]\)\?0*[3-5]\([^0-9][^/]*\)\?'

另一種方法是使用find報告文件列表,但使用更高級的語言perl來過濾該列表:

find . -print0 | perl -l -0ne '
 if (m{[^/]*\z}) {
   for $n ($& =~ /\d+/g) {
     if ($n >= 3 && $n <= 5) {
       print;
       next LINE;
     }
   }
 }'

在這裡,使用perl從每個文件的基本名稱中提取所有十進制數字序列,如果這些數字序列中至少有一個表示 3..5 範圍內的數字,則輸出文件。

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