Bash globbing 匹配除具有特定副檔名的文件之外的所有文件,適用於包含點字元的文件名
我正在用音頻文件做一些事情,大多數但不是全部都是 mp3 文件。現在我想只對不是 mp3 文件的文件執行一些命令,或者只對那些沒有
.mp3
副檔名的文件執行一些命令。我認為自己非常擅長正則表達式,但不擅長文件通配,這在意想不到的方面略有不同。
我環顧四周,從其他 SO & SE 答案中了解到 Bash 具有“擴展的 globbing”,允許我這樣做:
file ../foo/bar/*.!(mp3)
但是除了形成文件副檔名的文件名之外,我的一些文件名中還有點:
../foo/bar/Naked_Scientists_Show_19.10.15.mp3 ../foo/bar/YWCS_ep504-111519-pt1_5ej4_41cc9320.mp3_42827d48daefaa81ec09202e67fa8461_24419113.mp3 ../foo/bar/eLife_Podcast_19.09.26.mp3 ../foo/bar/gdn.sci.080428.bg.science_weekly.mp3
似乎 glob 從第一個點開始匹配,而不是從最後一個點開始匹配。我查看了文件,但似乎它們遠不如正則表達式強大。但是我並沒有真正了解所有內容,因為我沒有花太多時間在 *nix shell 上。
我是否錯過了一些仍然可以使用 Bash globbing 執行此操作的方法?如果沒有,使用 find 或其他工具實現相同目標的方法仍然值得了解。
*.!(mp3)
匹配 onfoo.bar.mp3
因為foo.
後面跟著bar.mp3
which is notmp3
。你想要
!(*.mp3)
在這裡,它匹配任何不以.mp3
.如果您想匹配名稱中至少包含一個文件
.
(除了會使它們成為隱藏文件的前導文件)但不以 . 結尾的文件.mp3
,您可以執行!(*.mp3|!(*.*))
.
GLOBIGNORE
shell 變數可用於限制匹配模式的文件名集。如果設置,則從匹配列表中刪除GLOBIGNORE
每個也匹配其中一個模式的匹配文件名。GLOBIGNORE
如果設置了該選項,則在不考慮大小寫的情況下執行nocaseglob
與模式的匹配。當設置且不為空時GLOBIGNORE
,文件名.
和..
總是被忽略 。GLOBIGNORE
但是,設置GLOBIGNORE
為非空值具有啟用dotglob
shell 選項的效果,因此所有其他以 ’ ’ 開頭的文件名.
都將匹配。.
要獲得忽略以 ’ ‘開頭的文件名的舊行為,請將’.*
’ 設為GLOBIGNORE
. 這dotglob
未設置時選項被禁用GLOBIGNORE
。$ touch a.b.mp3 .c.mp3 foo.tgz .bar $ echo * a.b.mp3 foo.tgz $ shopt -s extglob; echo *.!(mp3) a.b.mp3 foo.tgz $ GLOBIGNORE='*.mp3'; echo * .bar foo.tgz