计算多个文件中行的出现次数

计算多个文件中行的出现次数

我有一些日志文件,需要对其进行 grep 并计算特定行的出现次数。

问题是我必须从第一个文件的特定行开始,并且只计算该行之后的出现次数。应彻底搜索所有其他文件。仅第一个文件需要限制为最后 x 行。

然后我需要将结果乘以 200。我想用一个命令来完成此操作。

这是一个使用 2 个日志文件的工作示例,但我很快需要将其扩展到 3 个文件,并希望有人能想出更好的方法来做到这一点:

expr `tail -n 5147 Log1.log.2013-11-18 | grep "The line I need to count" | wc -l` + `cat Log2.log | grep "The line I need to count" | wc -l` | awk '{print $1"*200"}' | bc

答案1

我认为您应该能够在第二只猫之后添加第三个文件:

expr `tail -n 5147 Log1.log.2013-11-18 | grep "The line I need to count" | wc -l` + `cat Log2.log Log3.log | grep "The line I need to count" | wc -l` | awk '{print $1"*200"}' | bc

例子:

$ echo abc > 1.txt 
$ echo cde > 2.txt 
$ echo def > 3.txt 
$ cat 1.txt 2.txt 3.txt | grep d 
cde 
def

答案2

任意数量文件的通用解决方案:

 for file1 in log1.txt log2.txt logN.txt; do
   for file2 in logA.txt logB.txt logC.txt; do
     for file3 in logD.txt logE.txt logF.txt; do
     match1=$(tail -n 5147 $file1 | grep -c 'The line');
     match2=$(grep -c "the line" $file2);
     match3=$(grep -c "the line" $file3);
     echo "($match1 + $match2 + $match3) * 200" | bc;
   done;
 done;
done

the line这将计算每个 s 的最后 5147 行中的出现次数$file1并将其保存为$match1.然后,它将计算the line每个 s 中的出现次数$file2并将其保存为以及每个asmatch2中出现的次数。然后,它会计算。file3$match3($match1 + $match2 + $match3) * 200

只需在您正在执行的操作中添加一个文件并修复语法即可:

echo "$(tail -n 5147 Log1.log.2013-11-18 | grep -c 'The line') \ 
      $(grep -c 'The line' Log2.log) $(grep -c 'The line' Log3.log)" | 
        awk '{print ($1+$2+$3)*200}' 

这里有一些技巧。grep -c计算匹配项而不是打印它们,因此不需要wc.awk可以做数学,所以不需要bc。我使用echo而不是expr因为我不再在 shell 中进行算术运算,只是回显三个搜索的结果并将它们传递给awk.这应该会导致如下结果:

echo "10 4 12" | awk '{print ($1+$2+$3)*200}' 

更简洁的版本:

echo $((($(tail -n 5147 Log1.log.2013-11-18 | grep -c "The line) + \ 
         $(grep -c "The line" Log2.log) + $(grep -c "The lne" Log3.log)) * 200))

这使用符号在 shell 中完成所有数学运算$(( ))。你可以尝试一下echo $((2*4))。它不太容易阅读,它扩展为:

echo "$(( ($file1_matches + $file2_matches + $file3_matches) * 200 ))"

答案3

我解决了在多个 CSV 文件中计算行数的类似问题。

我有一个很大的 CSV 文件列表 - 脚本的输出,因此它们具有相同的字段。我对具有有效值的行数感兴趣。

完成这个技巧的命令是

awk -F, '{if ($5>0.0) print $5}' va.2021-04-11.153123.csv va.2021-04-11.111709.csv | wc -l
  • -F,将分隔符设置为,(我的 CSV 文件被,分隔)
  • '{if ($5>0.0) print $5}'awk是告诉我们要做什么的 “脚本” :
    • 如果第 5 个字段大于0.0则打印第 5 个字段
    • 然后通过管道将其wc-l标志一起计算输出中的行数
  • va.2021-04-11.153123.csv va.2021-04-11.111709.csv是两个 CSV 文件的空格分隔列表

相关内容