我想计算文件夹中元素的数量。我想到了
function lsc { /bin/ls -l $1 | sed 1d | wc -l }
Run Code Online (Sandbox Code Playgroud)
但后来我想起了awk人们如何减少这种管道,摆脱多余的greps 和seds。那么,你会怎么做awk呢?
不需要ls, sed,wc或awk。
如果你只是想计算一个模式扩展到多少个名字,那么你可以用
set -- *
echo "$#"
Run Code Online (Sandbox Code Playgroud)
该set命令将位置参数($1、$2等)设置为与*模式匹配的名称。这会自动将特殊变量$#设置为设置位置参数的数量,即与给定模式匹配的名称数量。
在bash具有命名数组的外壳中或外壳中,您可以使用
names=(*)
echo "${#names[@]}"
Run Code Online (Sandbox Code Playgroud)
其工作原理类似,但将names数组的元素设置为*模式扩展产生的名称。变量扩展${#names[@]}将是names数组中元素的数量。
这样做的一个问题是,如果模式不匹配任何内容,它将保持未展开状态,因此您的计数为 1(即使目录为空)。要在bashshell 中修复此问题,请将nullglobshell 选项设置为shopt -s nullglob. 通过设置此 shell 选项,将完全删除不匹配任何内容的模式。
在 中bash,如果您还想计算隐藏名称,请将dotglobshell 选项设置为shopt -s dotglob.
您的函数可能如下所示bash:
lsc () (
shopt -s nullglob
set -- "$1"/*
echo "$#"
)
Run Code Online (Sandbox Code Playgroud)
请注意( ... )函数体的使用,以避免nullglob在调用 shell 中进行设置。
或者,对于/bin/sh:
lsc () {
set -- "$1"/*
if [ -e "$1" ] || [ -L "$1" ]; then
echo "$#"
else
echo 0
fi
}
Run Code Online (Sandbox Code Playgroud)
if此处的语句确保第一个位置参数是实际文件的名称,而不是未扩展的模式(由于不匹配任何内容)。该-e(“存在”)必须为真为我们信任的数量$#。如果它不是真的,那么我们另外检查名称是否引用了-L测试的符号链接。如果这是真的,我们知道模式扩展到的第一件事是“死”符号链接(指向不存在文件的符号链接),我们相信$#这是正确的。如果两个测试都失败,我们知道我们没有匹配任何东西,因此输出0.