【问题标题】:Using diff for two files and send by email [closed]对两个文件使用差异并通过电子邮件发送[关闭]
【发布时间】:2015-11-22 19:06:06
【问题描述】:

我有如下文件。我每 5 分钟使用一次 crontab 检查文件,看看系统是否添加了一个文件,例如:AIR_2015xxxxT0yyyyyyyy.cfg。然后我需要在最后一个和最后一个之前自动使用diff命令。

AIR_20151021T163514000.cfg
AIR_20151026T103845000.cfg
AIR_2015xxxxT0yyyyyyyy.cfg

我想在如下脚本中执行此操作:

#!/bin/bash
/var/opt/fds/
diff AIR_2015xxxxT0yyyyyyyy.cfg AIR_20151026T103845000.cfg > Test.txt

body(){
cat body.txt
}
(echo -e "$(body)") | -a Test.txt mailx -s 'Comparison' user@email.com

【问题讨论】:

  • 那么...运行脚本时会出现什么错误?还是您只是在编写类似 shell 的元代码并希望其他人能完成繁重的工作?
  • @ghoti 实际上我认为你没有很好地阅读我的问题我每天都有很多文件,我想在最后一个文件和上次之前使用 diff 命令。
  • 大多数系统没有命令-a,所以这会带来问题。您对body 函数的使用很奇特;你应该可能使用类似的东西:mailx -a Test.txt -s 'Comparison' user@email.com < body.txt。但是还有很多工作要做,以确保您选择最新的以前的文件,而不是硬编码。您有一个完全固定的电子邮件正文,这有点奇怪。我还建议在文件附件的名称中使用日期/时间。
  • @JonathanLeffler 我亲爱的电子邮件没有问题我可以收到电子邮件但我的问题是差异我无法自动完成例如在每次修改后比较 2 个文件的最后一个和最后一个之前
  • 最新的文件名是否真的包含一个x序列和一个y序列,或者你正在寻找最新的文件和前一个文件,两者都有系统名称?查看数字名称是否足以确定最新的名称,还是我们必须担心名称“较旧”的文件比名称“较新”的文件被修改得更晚?如果新文件有 x 和 y,什么代码负责将其重命名为全数字名称?给定使用 ISO 8601 表示法(或多或少)的系统名称,按简单排序顺序的名称在最后。

标签: linux bash shell unix awk


【解决方案1】:

给定目录/var/opt/fds中的文件列表,名称格式为:

AIR_YYYYmmddTHHMMSSfff.cfg

其中字母Y代表年份,m代表月份,d代表日,H代表小时,M代表分钟,S代表秒,f代表小数(毫秒),那么你需要建立两个最近的目录中的文件进行比较。

一种方法是:

cd /var/opt/fds || exit 1

old=
new=
for file in AIR_20[0-9][0-9]????T?????????.cfg
do
    old=$new
    new=$file
done

if [ -n "$old" ] && [ -n "$new" ]
then
    diff "$old" "$new" > test.txt
    mailx -a test.txt -s 'Comparison' user@example.com < body.txt
fi

请注意,如果新文件的名称包含字母xy如问题和cmets所示,它将列在包含时间戳为数字的名称之后,因此将被拾取为新文件。它还假定在/var/opt/fds 目录中写入权限,并且邮件正文文件也存在于该目录中。如有必要,这些假设可以很容易地修复。 test.txt 文件在发送后也应删除,您可以在发送电子邮件之前检查它是否为非空(以防两个最近的文件实际上相同)。您可以在生成的包含差异的文件名中嵌入时间戳,而不是使用test.txt

output="diff.$(date +'%Y%m%dT%H%M%S000').txt"

然后使用$output 代替test.txt

测试确保既有旧名称又有新名称。模式匹配比它可能的更草率,但使用[0-9] 或适当的子范围([01][0-3][0-2][0-5])作为问号会使模式变得难以阅读:

for file in AIR_20[0-9][0-9][01][0-9][0-3][0-9]T[0-2][0-9][0-5][0-9][0-5][0-9][0-9][0-9][0-9].cfg

它也可能提供很少的额外保护。当然,如图所示,它给系统带来了 Y2.1K 危机,并不是说很难解决。您也可以根据今天的日期来缩小有效日期的范围,但要注意年底等。您可能会决定只需要上个月左右的条目。

使用通配符通常比尝试解析 lsfind 输出要好。在这种情况下,如果文件名的名称中有一组受限制的字符(没有换行符、没有空格或制表符、没有引号、没有美元符号等),则可以使用 findls —但是,如果您必须处理随机最终用户创建的任意名称,那么这些工具就不合适了。 (ls 命令用奇怪的名字做了各种奇怪的事情,而且在面对用户的诅咒时基本上很难可靠地使用。可以使用find 命令及其-print0 选项,特别是如果你有一个@ 987654345@ 识别 -z 以使用以 null 结尾的“行”,而 xargs 支持 -0 也可以处理此类行 - 但您必须非常小心。)

请注意,此方案不会记录最后分析的文件(因此,如果一个小时内没有新文件出现,您可能会发送十几个相同差异的副本),也不会直接报告文件名(但使用diff -udiff -c 会在输出中包含不同的文件名)。同样,如果合适(可能是),这些问题可以得到解决。记录比较过的文件可能是最困难的工作。即使这样也不错:

echo "$old" "$new" >> reported.diffs

记录已处理的内容;那么

if grep -q "$old $new" reported.diffs
then : Already processed
else : Process $old and $new
fi

【讨论】:

    猜你喜欢
    • 2012-04-11
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    相关资源
    最近更新 更多