在bash中匹配*.jpg但不匹配*.foo.jpg

在bash中匹配*.jpg但不匹配*.foo.jpg,bash,glob,Bash,Glob,这一定很简单,但我想不出来 for filename in *[^\.foo].jpg do echo $filename done 而不是匹配的文件名,echo显示模式: + echo '*[^.foo].jpg' *[^.foo].jpg 目的是查找以.jpg结尾的所有文件,而不是.foo.jpg 编辑:根据(被误解的)建议尝试此操作: 用于*[!“.foo”].jpg中的文件名 还是没有 在bash中,如果glob模式没有匹配项,bash将返回模式本身。您可以使用nullglobshe

这一定很简单,但我想不出来

for filename in *[^\.foo].jpg
do
echo $filename
done
而不是匹配的文件名,
echo
显示模式:

+ echo '*[^.foo].jpg'
*[^.foo].jpg
目的是查找以
.jpg
结尾的所有文件,而不是
.foo.jpg

编辑:根据(被误解的)建议尝试此操作:

用于*[!“.foo”].jpg中的文件名


还是没有

在bash中,如果glob模式没有匹配项,bash将返回模式本身。您可以使用
nullglob
shell选项更改此行为,该选项可以如下打开:

shopt -s nullglob
这在bash手册页中标题为的部分中进行了描述

至于它不匹配的原因,很简单,您没有任何匹配的文件。这可能是由于您使用的
^
通常不是有效的全局元字符。就glob而言,
^
只是匹配一个文本
^
。而且,
[…]
可能也不会做您认为它能做的事情

有关有效glob元字符的说明,请参阅bash手册页的部分

不能编写返回“所有以.jpg结尾但不以.foo.jpg结尾的文件”的glob模式。最简单的方法是对所有jpg文件(
*.jpg
)进行全局搜索,然后过滤掉代码块中以
foo.jpg
结尾的文件

for filename in *.jpg
do
    [[ $filename = *.foo.jpg ]] && continue
    echo $filename
done

在bash中,如果glob模式没有匹配项,bash将返回模式本身。您可以使用
nullglob
shell选项更改此行为,该选项可以如下打开:

shopt -s nullglob
这在bash手册页中标题为的部分中进行了描述

至于它不匹配的原因,很简单,您没有任何匹配的文件。这可能是由于您使用的
^
通常不是有效的全局元字符。就glob而言,
^
只是匹配一个文本
^
。而且,
[…]
可能也不会做您认为它能做的事情

有关有效glob元字符的说明,请参阅bash手册页的部分

不能编写返回“所有以.jpg结尾但不以.foo.jpg结尾的文件”的glob模式。最简单的方法是对所有jpg文件(
*.jpg
)进行全局搜索,然后过滤掉代码块中以
foo.jpg
结尾的文件

for filename in *.jpg
do
    [[ $filename = *.foo.jpg ]] && continue
    echo $filename
done

实际上,您可以使用extglob来执行此操作。要演示,请复制并粘贴以下代码:

shopt -s extglob
cd "$(mktemp -d "${TMPDIR:-/tmp}/test.XXXXXX")" || exit
touch hello.txt hello.foo hello.foo.jpg hello.jpg
printf '%q\n' !(*.foo).jpg
输出应为:

hello.jpg

实际上,您可以使用extglob来执行此操作。要演示,请复制并粘贴以下代码:

shopt -s extglob
cd "$(mktemp -d "${TMPDIR:-/tmp}/test.XXXXXX")" || exit
touch hello.txt hello.foo hello.foo.jpg hello.jpg
printf '%q\n' !(*.foo).jpg
输出应为:

hello.jpg


您确定
[^…]
是有效的
bash
语法吗?为1添加一些示例文件名。您希望匹配的文件,2。您不想匹配的文件。使用
[^…]
是否意味着对char类的否定?在shell中,您可以使用
[!…]
,并了解我所说的字符类的含义。祝你好运。@Jortstek,…为了弄清楚你为什么会看到这样的行为:方括号定义了一个字符类。根据定义,字符类只匹配一个字符,而不是多个字符,就像扩展名一样……尽管在bash中,
^
确实可以工作;不过,这是POSIX之外的扩展,它只需要
。不过仍然没有意义,因为这是字符类反转,而不是负前瞻。@Jortstek,如果你认为我建议你使用
*[!“.foo”].jpg
,你读得不够仔细。我从未给出过那个建议。您确定
[^…]
是有效的
bash
语法吗?为1添加一些示例文件名。您希望匹配的文件,2。您不想匹配的文件。使用
[^…]
是否意味着对char类的否定?在shell中,您可以使用
[!…]
,并了解我所说的字符类的含义。祝你好运。@Jortstek,…为了弄清楚你为什么会看到这样的行为:方括号定义了一个字符类。根据定义,字符类只匹配一个字符,而不是多个字符,就像扩展名一样……尽管在bash中,
^
确实可以工作;不过,这是POSIX之外的扩展,它只需要
。不过仍然没有意义,因为这是字符类反转,而不是负前瞻。@Jortstek,如果你认为我建议你使用
*[!“.foo”].jpg
,你读得不够仔细。我从未给出过这样的建议。这不是唯一的错误——字符类的含义显然与OP的意图不同(因为写
[^.foo]
没有意义,而不是确切的语义等价物
[^.fo]
[.of^]
)……无论如何,
^
的每一位都与任何其他排序字符一样有效,也就是说,它表示自身。如果需要一个否定,那么是的,需要
而不是。。。但是考虑到上下文,我觉得这很可疑。@CharlesDuffy:你是对的。关于
^
,我已经重新表述了我的答案。我建议将
=
更改为
=
,以鼓励符合POSIX的习惯:也可以将
echo$filename
更改为
echo“$filename”
,或者更好地
printf“%s\n'$filename”
;请参见re:first proposed substitution和POSIX
echo
spec at(尤其是应用程序用法和基本原理部分)re:the Late。这不是唯一的错误——字符类的含义显然与OP的意图不同(因为编写
[^.foo]没有意义)
而不是确切的语义等价物
[^.fo]
[.of^]
)……无论如何,
^
与任何其他排序字符一样有效,也就是说,它代表它自己。如果需要一个否定,那么是的,需要
而不是。。。但是考虑到上下文,我觉得这很可疑。@CharlesDuffy:你是对的。我重新措辞了