Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 在bash中,计算按分数级别分组的文件数_Linux_Loops - Fatal编程技术网

Linux 在bash中,计算按分数级别分组的文件数

Linux 在bash中,计算按分数级别分组的文件数,linux,loops,Linux,Loops,我需要遍历一个目录。对目录中的每个文件执行另一个书面脚本,并检查输出是否等于五个可能标记中的任何一个(“A”,“B”,“C”,“D”,“F”)。for循环旨在分别统计五个标记类别中的文件数量 $1,$2是此脚本的参数。 $1是另一个书面脚本的名称,$2是目录的名称 这是我的部分代码 for file in $(ls $2) do if (( $($1 $file) == "A" )) then (( countA+=1 ))

我需要遍历一个目录。对目录中的每个文件执行另一个书面脚本,并检查输出是否等于五个可能标记中的任何一个(
“A”
“B”
“C”
“D”
“F”
)。
for
循环旨在分别统计五个标记类别中的文件数量

$1
$2
是此脚本的参数。
$1
是另一个书面脚本的名称,
$2
是目录的名称

这是我的部分代码

for file in $(ls $2)
do
       if (( $($1 $file) == "A" ))
       then
            (( countA+=1 ))
       elif (( $($1 $file) == "B" ))
       then
            (( countB+=1 ))
       elif ((  $($1 $file) == "C" ))
       then
            (( countC+=1 ))
      
       fi
结果很奇怪

    A:100
    B:0
    C:0
    D:0
    F:0
这让我很困惑,为什么文件夹中的100个文件都标记为“A”,实际上只有7个文件是“A”。

问题是,
(==)
进行数字比较,但您试图比较字符串(不管怎样,还是字母)。假设
$($1$file)
的计算结果为“B”;然后表达式本质上变成了
((B==A))
,因此shell尝试将“A”和“B”都转换为数字,以便对它们进行比较。它所做的是将它们作为变量名进行计算,但是没有定义
B
A
,因此两者都默认为0,并且您有
((0==0))
。。。这是真的。本质上,无论打印什么
$1$file
,它都将匹配“A”,因为它们的计算结果都是0

修复它的最快方法是使用字符串比较(注意:我还修复了一些缺少的双引号):

更好的解决方案是使用
案例

case "$($1 "$file")" in
    A) (( countA+=1 ));;
    B) (( countB+=1 ));;
    C) (( countC+=1 ));;
    D) (( countD+=1 ));;
    F) (( countF+=1 ));;
esac
但是,如果您有bash v4或更高版本,使用关联数组而不是单独的变量进行计数可能会更简单:

#!/bin/bash

declare -A count=([A]=0 [B]=0 [C]=0 [D]=0 [F]=0)

for file in "$2"/*    # This is a better way to iterate over a directory's contents
do
    (( count["$($1 "$file")"] += 1 ))
done

for grade in A B C D F
do
    echo "$grade:${count[$grade]}"
done

嗨,非常感谢你,非常好!代码做得很好,缩进很好,这样更容易理解!但是有一件事,您还需要包括一个来自命令行的示例调用,我看到您正在执行
$($1$file)
,这意味着
$1
是一个类似于
sed
(或
cat
,或
wc
或???)的命令,但不知道如何调用它,我们真的无能为力。添加类似于./myScript wc`之类的内容,以便我们知道您是如何使用它的。。。。但是,似乎您只想计算以
A
等开头的文件。最好在A*((countA++)中使用
大小写“${file}”;;B*);;C*)。。。。。。。;esac
。祝你好运。使用<代码>处理$(ls$2)中的文件时会出现问题;执行…。在$2中尝试文件
;执行…
。还有其他事情,你把代码粘贴到了吗?修复在此处发现的所有错误/警告。祝你好运。还有最好的调试技巧(简短地添加
echo之类的语句"file=|$file | countA=|$countA |…etc
,是使用shell调试功能。在脚本顶部附近,添加一行
set-x
,您将看到每一行都用变量名替换的变量值执行。您可以使用
set+x
关闭它。祝您好运!感谢您的帮助,它成功了!字符串比较解决了我的问题,我还发现带有数值比较==的
`./$1$file`
#!/bin/bash

declare -A count=([A]=0 [B]=0 [C]=0 [D]=0 [F]=0)

for file in "$2"/*    # This is a better way to iterate over a directory's contents
do
    (( count["$($1 "$file")"] += 1 ))
done

for grade in A B C D F
do
    echo "$grade:${count[$grade]}"
done