如果文件采用双支架试验和通配符存在猛砸检查 [英] Bash check if file exists with double bracket test and wildcards
问题描述
我写一个Bash脚本,需要检查文件是否存在,看起来像。* $ 1 *分机
我可以POSIX做到这一点真的很容易测试为 [-f * $ 1 *。EXT]
返回true,但使用双支架 [-f * $ 1 *。转]
失败。
I am writing a Bash script and need to check to see if a file exists that looks like *.$1.*.ext
I can do this really easily with POSIX test as [ -f *.$1.*.ext ]
returns true, but using the double bracket [[ -f *.$1.*.ext ]]
fails.
这是只是为了满足好奇心,因为我不能相信的扩展测试就不能挑出来的文件是否存在。我知道,我可以使用 [`LS * $ 1 *。ext`]
,但将匹配如果有多个匹配。我大概是管厕所
或东西,但似乎笨重。
This is just to satisfy curiosity as I can't believe the extended testing just can't pick out whether the file exists. I know that I can use [[ `ls *.$1.*.ext` ]]
but that will match if there's more than one match. I could probably pipe it to wc
or something but that seems clunky.
有没有使用双括号来检查使用通配符的文件存在一个简单的方法?
Is there a simple way to use double brackets to check for the existence of a file using wildcards?
编辑:我看到 [-f`LS -U * $ 1 * ext`]。]
工作,但我还是preFER以不用调用LS。
I see that [[ -f `ls -U *.$1.*.ext` ]]
works, but I'd still prefer to not have to call ls.
推荐答案
无论 [-f ...]
也不 [ -f ...]]
(也没有其他文件的测试运营商)都设计有的模式工作的(又名水珠,通配符前pressions) - 他们总是相互preT他们的操作数作为一个的文字的文件名[1]
Neither [ -f ... ]
nor [[ -f ... ]]
(nor other file-test operators) are designed to work with patterns (a.k.a. globs, wildcard expressions) - they always interpret their operand as a literal filename.[1]
如果一个模式(水珠)相匹配的简单的技巧为测试的一个的文件是使用的辅助功能
A simple trick to test if a pattern (glob) matches exactly one file is to use a helper function:
existsExactlyOne() { [[ $# -eq 1 && -f $1 ]]; }
if existsExactlyOne *."$1".*.ext; then # ....
如果你只是有兴趣,是否有的任何的匹配 - 即的一个或多个的 - 功能更加简单:
If you're just interested in whether there are any matches - i.e., one or more - the function is even simpler:
exists() { [[ -f $1 ]]; }
如果你想的避免功能,它得到的棘手
的买者的:(尽管这可能是固定的)这种解决方案并不正规文件的目录进行区分,例如
Caveat: This solution does not distinguish between regular files directories, for instance (though that could be fixed.)
if [[ $(shopt -s nullglob; set -- *."$1".*.ext; echo $#) -eq 1 ]]; then # ...
- 命令替换内部的code(
$(...)
)进行以下操作:-
禁用了javascript -s nullglob
指示bash的扩展模式的的空的字符串,如果有的没有的匹配 - 设置
- ...
分配模式扩展位置参数(结果$ 1
,$ 2
,...)子shell,其中的命令替换运行。 -
回声$#
简单重复定位参数,然后对应匹配的文件的计数的计数; - The code inside the command substitution (
$(...)
) does the following:shopt -s nullglob
instructs bash to expand the pattern to an empty string, if there are no matchesset -- ...
assigns the results of the pattern expansion to the positional parameters ($1
,$2
, ...) of the subshell in which the command substitution runs.echo $#
simply echoes the count of positional parameters, which then corresponds to the count of matching files;- 在
[...]
它的从不的工作原理:该模式一直被视为一个文字的文件测试操作。 - 在
[...]
它的只有的正常工作如果恰好是只有一个匹配的。- 如果没有匹配:
- 文件测试操作人员认为该模式为文字,如
nullglob
为OFF(默认设置),或者,如果nullglob
为ON,条件总是返回true,因为它降低到-f
,其中,由于缺少操作数,不再是跨preTED作为一个文件测试,但作为一个的非空的字符串的(和非空的字符串的计算结果为真))。
- With
[[ ... ]]
it never works: the pattern is always seen as a literal by the file-test operator. - With
[ ... ]
it only works properly if there happens to be exactly ONE match.- If there's NO match:
- The file-test operator sees the pattern as a literal, if
nullglob
is OFF (the default), or, ifnullglob
is ON, the conditional always returns true, because it is reduced to-f
, which, due to the missing operand, is no longer interpreted as a file test, but as a nonempty string (and a nonempty string evaluates to true)).
这篇关于如果文件采用双支架试验和通配符存在猛砸检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- The file-test operator sees the pattern as a literal, if
- If there's NO match:
- 文件测试操作人员认为该模式为文字,如
- 如果没有匹配:
此外,如果你只是有兴趣,是否有的任何的匹配 - 即的一个或多个的 - 只需更换
-eq
与-ge
。Again, if you're just interested in whether there are any matches - i.e., one or more - simply replace
-eq
with-ge
.[1]结果
由于@Etan赖辛格指出了一条评论,在[...]
(单括号的语法),外壳扩展模式的前<的情况下, / EM>的-f
运营商甚至认为它(正常的命令行解析规则适用)。[1]
As @Etan Reisinger points out in a comment, in the case of the[ ... ]
(single-bracket syntax), the shell expands the pattern before the-f
operator even sees it (normal command-line parsing rules apply).相反,不同的规则适用于bash中的
[...]
,它被解析的区别的,在这种情况下,简单地将该模式为的文字的(即不展开)。By contrast, different rules apply to bash's
[[ ... ]]
, which is parsed differently, and in this case simply treats the pattern as a literal (i.e., doesn't expand it).无论哪种方式,它不会工作(强劲和predictably)与图案:
Either way, it won't work (robustly and predictably) with patterns:
-