我想知道是否可以使用sed命令查找2个模式之间的范围(在本例中为日期),并将范围中的这些行输出到新文件。
现在,我只是查看一个文件,并在文件FileMoverTransfer.log的时间范围内获取行。但是,在一段时间后,这些日志将移动到带有后缀的新日志文件,例如FileMoverTransfer.log-20180404-xxxxxx.gz。这是我目前的代码:
sed -n '/^'$start_date'/,/^'$end_date'/p;/^'$end_date'/q' FileMoverTransfer.log >> /public/FileMoverRoot/logs/intervalFMT.log
虽然这不起作用,因为sed无法查看以FileMoverTransfer.log开头的目录中的所有文件?
sed -n '/^'$start_date'/,/^'$end_date'/p;/^'$end_date'/q' FileMoverTransfer.log* >> /public/FileMoverRoot/logs/intervalFMT.log
非常感谢任何帮助。谢谢!
答案 0 :(得分:1)
范围运算符仅在单个文件中运行,因此如果开始位于一个文件中且结尾位于另一个文件中,则无法使用它。
您可以使用cat
连接所有文件,并将其传递给sed
:
cat FileMoverTransfer.log* | sed -n "/^$start_date/,/^$end_date/p;/^$end_date/q" >> /public/FileMoverRoot/logs/intervalFMT.log
而不是引用和取消引用sed
命令,您可以使用双引号,以便在其中扩展变量。如果变量包含空格,这也可以防止出现问题。
答案 1 :(得分:0)
awk解决方案
由于OP确认awk
解决方案可以接受,我发布。
(gunzip -c FileMoverTransfer.log-*.gz; cat FileMoverTransfer.log ) \
|awk -v st="$start_date" -v en="$end_date" '$1>=st&&$1<=en{print;next}$1>en{exit}'\
>/public/FileMoverRoot/logs/intervalFMT.log
此解决方案在功能上几乎与Barmar的sed
解决方案完全相同,不同之处在于他的解决方案(如OP)将在与结束日期匹配的第一条记录上打印并退出,而我的解决方案将打印与结束日期并退出结束日期后的第一个记录,而不打印它。
一些评论:
OP未指定日期格式。我想这是一种与普通字符串顺序兼容的格式,否则应该使用一些转换函数。
文件FileMoverTransfer.log-*.gz
必须以这样的方式命名,即它们的字母排序符合时间顺序(可能就是这种情况。)
我认为日期与空格的其余部分分开。如果不是,则必须向-F
提供awk
选项。例如,如果日期以-
分隔,则必须写awk -F- ...
awk
比sed
快得多,因为awk
只是查找分隔符(空格或-F
提供的任何内容)而{ {1}}执行正则表达式匹配。
我的代码中没有 range 的概念,只有日期比较。我认为行是有序的唯一地方是当我说sed
时,当行比结束日期更新时退出。如果删除最终模式及其动作,代码将贯穿整个输入,但您可以放弃订购文件的要求。