例如,我有一个名为
A_1.txt A_t_1.txt A_ts_1.txt A_tsa_1.txt
在一个目录中~/admin/packages/
。
我正在构建一个 for 循环,通过通配符到 A_1.txt
for f in ~/admin/packages/*_1.txt
很明显,这可能会通配到这些文件中的任何一个。
具体来说,我想使用“例外”命令(如果存在)对任何文件表示 glob,只要它之前没有t
, s
, 。a
_1.txt
编辑:我忘了提及我将路径存储为变量。
PROJECT="~/admin/packages/*_1.txt"
for f in ${PROJECT}...
答案1
您可以使用以下extglob
模式来执行此操作bash
:
!(*t|*s|*a)_1.txt
extglob
首先启用(如果未启用):
shopt -s extglob
然后你可以这样做:
for f in ~/admin/packages/!(*t|*s|*a)_1.txt; do ##Something; done
例子:
$ echo *_1.txt
A_1.txt Ab_1.txt A_t_1.txt A_ts_1.txt A_tsa_1.txt
$ shopt -s extglob
$ echo !(*t|*s|*a)_1.txt
A_1.txt Ab_1.txt
缩短(感谢混乱):
!(*[tsa])_1.txt
答案2
你可以将你的PROJECT
var 设置为~/admin/packages/*[^tsa]_1.txt
PROJECT="~/admin/packages/*[^tsa]_1.txt"
如果可以修改的话。
答案3
使用case
语句来清除异常,如下所示:
for f in ${PROJECT}; do
case "$f" in *[tsa]_1*) continue;; esac
# ... actual work here ...
done
答案4
(在 bash 中)您的请求的确切答案是使用GLOBIGNORE
:
通过执行此命令:
LESS=+/'^ *GLOBIGNORE' man bash
读:
GLOBIGNORE
以冒号分隔的模式列表,定义路径名扩展要忽略的文件名集。如果与路径名扩展模式匹配的文件名也与 GLOBIGNORE 中的模式之一匹配,则会将其从匹配列表中删除。
所以,通过GLOBIGNORE
这样设置:
$ ls *
A_1.txt A_t_1.txt A_ts_1.txt A_tsa_1.txt
$ GLOBIGNORE=*t_1.txt:*s_1.txt:*a_1.txt
$ ls *
A_1.txt
之后您可以使用 恢复GLOBIGNORE
为空unset GLOBIGNORE
。