我正在尝试编写一个查看.txt文件的脚本,并确定第一个数字是否大于或等于100.如果是,则发送电子邮件,如果不是,则不执行任何操作。
以下是.txt文件的示例
vi output.txt
108
由于该数字超过100,因此应发送一封电子邮件:
电子邮件示例
You have 108 errors
这是我到目前为止所得到的:
#!/bin/bash
filename = '/home/tted01/SPOOL/error.txt'
while read -r line
do
id = $(cut -c-3 <<< "$line")
echo $id >> /home/tted01/SPOOL/output.txt
done < "$filename"
mailx -s "ERRORS" ted.neal@gmail.com -- -f ted.neal@gmail.com < /home/tted01/SPOOL/output.txt
sleep 5
exit 0
我无法弄清条件语句以及如何解析变量。
答案 0 :(得分:2)
这是一个简单的Perl脚本。由于我们需要同时发送消息和文件,因此问题中的示例将更改为 attach 文件。这看起来适合于一个小文本文件,无论如何都会在正文中讨论这些内容。使用mailx
还有其他方法可以执行此操作,请参阅系统上的man mailx
。
use warnings;
use strict;
my $file = '/home/tted01/SPOOL/error.txt';
my $mark = 100;
# Slurp the whole file into a variable
my $cont = do {
open my $fh, '<', $file or die "Can't open $file -- $!";
local $/;
<$fh>;
};
# Pull the first number
my ($num) = $cont =~ /^(\d+)/;
if ($num > $mark)
{
my $body = "You have $num errors.";
my $cmd_email = "echo $body | " .
"mailx -a $file -s \"ERROR\" ted.neal\@gmail.com";
system($cmd_email) == 0 or die "Error sending email -- $!";
}
由于这显然是一个足够小的文件,因此可以一次性读入变量。我们通过一个简单的正则表达式提取文件中的第一个数字。 (“数字”被理解为连续数字,最多为数字以外的任何数字。)
电子邮件命令是通过system
执行的,在Perl中使用sh
。如果执行命令没有错误,Perl的system
将返回0
,因此我们对此进行测试。请注意,这并不告诉我们命令本身是如何做的,只是它运行正常。如果需要,所有这些都可以通过其他方式完成 - 可以使用反引号(qx
)来获取输出,并在命令中使用可能的流重定向来获取错误。此外,如果需要,可以显式调用bash
。
这是如何撰写邮件的另一个选项。如果文件确实很小,您可以将其内容包含在邮件正文中。
此代码段之前和之后的所有内容都保持如上。
my ($num) = $cont =~ /^(\d+)/;
chomp($cont);
my $body = "You have $num errors. Log file: $file. Content: $cont";
my $cmd_email = "echo $body | mailx -s \"ERROR\" ted.neal\@gmail.com";
请注意,我们必须小心新行,因此chomp
并且邮件正文中没有换行符。所以这推动了一点。
如果日志文件可能太大或者可能不太大,您可以检查行数并且可能包括前5或10(并附加文件),或者包括上面的整个文件(如果足够小)。这在Perl中很容易处理。你可以进一步完善这一点。最后,如果事情发展并变得复杂,您可以将Perl模块用于电子邮件。
出现了一个非常合理的问题 - 如果数字不是文件中的第一个,该怎么办?例如,如果它是第二行的第一件事怎么办?
如果文件很小,人们仍然可以将其读入上面的变量,并使用(更复杂的)正则表达式来查找模式。例如,如果数字是第二行的第一件事
my ($num) = $cont =~ /.*\n(\d+)/;
该模式直接与\n
匹配换行符,并捕获其后的第一个数字。由于没有/s
或此类修饰符,因此换行符与.
不匹配,因此贪婪的.*
会根据需要停在第一个换行符处。
然而,随着更复杂的要求出现,这会变得非常快。因此,只需逐行处理。
# Instead of reading all content into $cont
open my $fh, '<', $file or die "Can't open $file -- $!";
my $num;
while (my $line = <$fh>)
{
if ($. == 2) { # $. is number of lines read
($num) = $line =~ /^(\d+)/;
last; # we are done, quit the loop
}
}
# Process the same way as above
我们使用Perl的内置特殊变量之一$.
,其中包含从(最后访问的)文件句柄中读取的行数。见Special Variables in perlvar。请注意,该行在<>
处读取,因此当我们处理第一行时,循环$.
内部为1
等。正则表达式是相同的,这是一个解释上面缺少。
匹配$line =~ m/.../
始终返回匹配的列表,因为它可以匹配多次,因此我们使用()
在列表中“捕获”它。由于这里只有一个,因此使用一个变量就足够了,因此($num)
。 m/
可能会被省略,您通常会这样看,=~ /.../
。
这是一个简单的条件,它是第二行。但是这样你也可以使用更复杂的东西。
答案 1 :(得分:1)
这里有bash脚本解决方案: -
#!/bin/bash
filename = '/home/tted01/SPOOL/error.txt'
while read -r line;
do
id =`echo $line`
if [ $id -gt 100 ]; then
mailx -s "You have $id errors" ted.neal@gmail.com < /home/tted01/SPOOL/output.txt
fi
sleep 5
done < filename