我有一些日志文件,需要对其进行 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
标志一起计算输出中的行数
- 如果第 5 个字段大于
va.2021-04-11.153123.csv va.2021-04-11.111709.csv
是两个 CSV 文件的空格分隔列表