你如何用awk替换sed和wc?(计算目录中的名称)

ych*_*che 3 sed awk wc

我想计算文件夹中元素的数量。我想到了

function lsc { /bin/ls -l $1 | sed 1d | wc -l }
Run Code Online (Sandbox Code Playgroud)

但后来我想起了awk人们如何减少这种管道,摆脱多余的greps 和seds。那么,你会怎么做awk呢?

Kus*_*nda 7

不需要ls, sed,wcawk

如果你只是想计算一个模式扩展到多少个名字,那么你可以用

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.