[英]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.