Bash

Bash globbing 匹配除具有特定副檔名的文件之外的所有文件,適用於包含點字元的文件名

  • December 13, 2019

我正在用音頻文件做一些事情,大多數但不是全部都是 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.mp3which is notmp3

你想要!(*.mp3)在這裡,它匹配任何不以.mp3.

如果您想匹配名稱中至少包含一個文件.(除了會使它們成為隱藏文件的前導文件)但不以 . 結尾的文件.mp3,您可以執行!(*.mp3|!(*.*)).

還有變數_GLOBIGNORE

GLOBIGNOREshell 變數可用於限制匹配模式的文件名集。如果設置,則從匹配列表中刪除GLOBIGNORE每個也匹配其中一個模式的匹配文件名。GLOBIGNORE如果設置了該選項,則在不考慮大小寫的情況下執行nocaseglob與模式的匹配。當設置且不為空時GLOBIGNORE,文件名...總是被忽略 。GLOBIGNORE但是,設置GLOBIGNORE為非空值具有啟用dotglobshell 選項的效果,因此所有其他以 ’ ’ 開頭的文件名.都將匹配。.要獲得忽略以 ’ ‘開頭的文件名的舊行為,請將’ .*’ 設為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

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