忽略遞歸 ls 中與否定 extglob 模式的所有匹配
我想使用 ls遞歸地列出與給定輸入模式匹配的目錄中的所有文件。(哦,這是在 Bash 中)。
我能想到的使用 ls 執行此操作的唯一方法是
shopt -s extglob
,然後將ls --ignore=pattern
選項與擴展 glob negate pattern 一起使用!( pattern-list )
。似乎有點迂迴否定忽略,但否則萬用字元不會遞歸。假設我已經有了要查看的目錄
dir
和要匹配的模式 asfile
,這是我目前的嘗試:
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 = *.c
和dir = 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 網站上。
提前致謝!
添加
globstar
shell 選項和-d
標誌ls
以不自動列出目錄內容怎麼樣?shopt -s extglob shopt -s globstar ls -d **/!(*.c)
GNU
ls
--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
.