我正在尝试计算一组日志文件中的条目数。其中一些日志的行不应计算(这些行的数量保持不变)。我想要解决这个问题的方法是一个Perl脚本,它遍历一个哈希,它将日志名称映射到一个单行程序,获取该特定日志的条目数(我认为这比几十个更容易维护if-else语句)
获取行数很简单:
wc -l [logfile] | cut -f1 -d " "
问题是当我需要从此值中减去1或2时。我尝试了以下方法:
expr( wc -l [logfile] | cut -f1 -d " " ) - 1
但这会导致错误:
Badly placed ()'s.
: Command not found.
如何对shell命令的输出执行算术运算?有更好的方法吗?
答案 0 :(得分:1)
显示少于bash
或任何类似bourne的shell的行数:
echo $(( $(wc -l <file) - 1 ))
要获得行数,请使用:
wc -l logfile | cut -f1 -d " "
此处需要 cut
,因为wc
会将文件名复制到其输出中。为避免这种情况,从而避免需要cut
,请通过stdin将输入提供给wc
:
wc -l <logfile
在现代(POSIX)shell中,算术是使用$((...))
完成的。因此,我们可以通过以下方式从行数中减去一个:
$(( $(wc -l <file) - 1 ))
答案 1 :(得分:0)
为了计算文件中的行数,向wc
和cut
进行搜索是有点笨拙的。
您的要求不是很清楚,但是这个Perl代码创建了一个哈希,它将当前目录中的每个日志文件与它包含的行数相关联。它的工作原理是将每个文件读入一个行数组,然后在标量上下文中评估该数组以给出行数。我希望很明显如何从每个行数减去一个恒定的增量。
use strict;
use warnings;
my %lines;
for my $logfile ( glob '*.log' ) {
my $num_lines = do {
open my $fh, '<', $logfile or die qq{Unable to open "$logfile" for input: $!};
my @lines = <$fh>;
};
$lines{$logfile} = $num_lines;
}
<强>更新强>
来自w.k
的评论后,我认为这个版本可能更好
use strict;
use warnings;
my %lines;
for my $logfile ( glob '*.log' ) {
open my $fh, '<', $logfile or die qq{Unable to open "$logfile" for input: $!};
1 while <$fh>;
$lines{$logfile} = $.;
}
答案 2 :(得分:0)
现有的答案是在perl
解决问题的方向,你提到过但你自己的实验是用shell语法编写的。
您表示tcsh
但expr
是Posix shell语法。
这是一个csh
脚本的示例,它计算文件中传递名称的行数,然后对行数进行算术运算。
set lines=`wc -l < $1`
@ oneless = ($lines - 1)
echo "There are $lines in $1 and minus one makes $oneless"
<强>测试强>
csh count.csh count.csh
There are 3 lines in count.csh and minus one makes 2