简体   繁体   English

我不明白 Bash 脚本中“$x*”中的 * 是什么

[英]I don't understand what the * in "$x*" in my Bash Script

Here's some code for some context.这是某些上下文的一些代码。

for x in {a..z};
do
    for y in $x*;do
        if  [ "$y" != "$x*" ]; then
        let "count++"

If someone can try to explain what that 2nd for loop does I would appreciate it.如果有人可以尝试解释第二个 for 循环的作用,我将不胜感激。 Thank you谢谢

It's a really inefficient and ugly way of counting how many files in the current directory start with the letters a through z.这是一种计算当前目录中有多少文件以字母 a 到 z 开头的低效和丑陋的方法。 The outer loop executes once for each letter, and for each one, the inner loop executes once for each file starting with that letter - $x* expands to a* through z* and then to files matching that pattern (Or just the pattern if none do, assuming nullglob is off. The if catches those cases though it has issues if the filename is literally a* etc.).外循环对每个字母执行一次,对于每个字母,内循环对以该字母开头的每个文件执行一次 - $x*扩展为a*z* ,然后扩展为匹配该模式的文件(或者只是模式,如果没有,假设nullglob关闭。如果文件名字面上是a*等, if捕获这些情况,但它有问题。

A better way to count the number of files matching a pattern in bash is to store all the filenames in an array using a single more efficient glob pattern, and then get the array's length:bash计算与模式匹配的文件数量的更好方法是使用单个更有效的 glob 模式将所有文件名存储在数组中,然后获取数组的长度:

shopt -s nullglob
files=([a-z]*)
count=${#files[@]}

By default ( shopt -u nullglob ), for the glob pattern foo* , if there are no files matching it, the pattern will expand to the literal string foo* .默认情况下( shopt -u nullglob ),对于 glob 模式foo* ,如果没有匹配它的文件,该模式将扩展为文字字符串foo* See the following example which you can try.请参阅以下示例,您可以尝试。

$ cat ../foo.sh
count=0
for x in {a..z}; do
    for y in $x*; do
        if  [ "$y" != "$x*" ]; then
            let "count++"
        fi
    done
done
echo $count
$ ls
a1 a2 b3 c4 z5
$ bash ../foo.sh
5
$ x=a
$ for file in $x*; do echo "$file"; done
a1
a2
$ x=b
$ for file in $x*; do echo "$file"; done
b3
$ x=f
$ for file in $x*; do echo "$file"; done
f*
$

Search for nullglob in the bash manual for more details.bash 手册中搜索nullglob以获取更多详细信息。

As others pointed out the code is not technically correct unless you are sure there are no filenames including a literal * char.正如其他人指出的那样,代码在技术上是不正确的,除非您确定没有包含文字*字符的文件名。 Or you can change [ "$y" != "$x*" ] to [ -e "$y" ] .或者您可以将[ "$y" != "$x*" ]更改为[ -e "$y" ]

$ ls -1
a1
a2
b3
c4
z5
z6*
$ cat ../foo.sh
count=0
for x in {a..z}; do
    for y in $x*; do
        if  [ -e "$y" ]; then
        #   ^^^^^^^^^^^
            let "count++"
        fi
    done
done
echo $count
$ bash ../foo.sh
6
$

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM