Bash

忽略遞歸 ls 中與否定 extglob 模式的所有匹配

  • February 13, 2013

我想使用 ls遞歸地列出與給定輸入模式匹配的目錄中的所有文件。(哦,這是在 Bash 中)。

我能想到的使用 ls 執行此操作的唯一方法是shopt -s extglob,然後將ls --ignore=pattern選項與擴展 glob negate pattern 一起使用!( pattern-list )。似乎有點迂迴否定忽略,但否則萬用字元不會遞歸。

假設我已經有了要查看的目錄dir和要匹配的模式 as file,這是我目前的嘗試:

ls -AR --ignore='!('"${file}"')' ${dir}

但是,這似乎沒有達到預期的效果,例如在目錄結構給出以下輸出的測試案例中ls -AR

   .:
   a  a.c  b  b.c  c  c.h  s

   ./s:
   a  a.c  b  b.c  c  c.h

我的命令file = *.cdir = s(完整命令ls -AR --ignore=!(*.c) s:)給出了這個輸出:

   ./s:
   a  a.c  b  b.c  c  c.h

我知道我可以很容易地將它通過管道傳輸到 grep 中,然後執行類似的操作ls -AR s | grep -v '.*.c'並獲得如下輸出:

   s:
   a
   b
   c
   c.h

但我正在尋找一種方法來做到這一點ls

抱歉,如果我不清楚,這是我第一次在 StackExchange 網站上。

提前致謝!

添加globstarshell 選項和-d標誌ls以不自動列出目錄內容怎麼樣?

shopt -s extglob
shopt -s globstar
ls -d  **/!(*.c)

GNUls --ignore選項採用標准文件名模式,而不是ksh擴展模式(什麼bash(並且bash唯一,不是ls)用 辨識extglob

所以你可以這樣做:

ls -AR --ignore='*.[ch]' --ignore='*.cpp'

但你不能這樣做:

ls -AR --ignore='!(*.[ch]|*.cpp)'

這只會忽略名為:!(foo.c|bar.cpp).

ls -AR --ignore=!(*.c)中,由於未引用該模式,bash因此會在將其傳遞給 之前嘗試對其進行擴展ls。因此,它將在目前目錄中查找名稱以 . 開頭"--ignore="且不以".c". 例如,如果有兩個文件,一個被呼叫--ignore=foo,一個被呼叫--ignore=bar,它將ls使用這四個參數執行:"ls", "-AR", "--ignore=bar", "--ignore=foo"

您可以(使用 GNU 查找)。

find . -regextype posix-extended -regex '.*\.([ch]|cpp)' -ls

或使用任何 POSIX find

find . \( -name '*.[ch]' -o -name '*.cpp' \) -exec ls -ld {} +

或者假設沒有指向目錄的符號連結:

shopt -s extglob globstar dotglob failglob
ls -ld -- **/*.@([ch]|cpp)

這一次,bash確實擴展了 globbing 模式並將文件列表傳遞給ls.

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