使用sed通过目录

时间:2018-04-04 19:30:42

标签: linux bash

我想知道是否可以使用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

非常感谢任何帮助。谢谢!

2 个答案:

答案 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- ...

  • 在这种情况下,
  • awksed快得多,因为awk只是查找分隔符(空格或-F提供的任何内容)而{ {1}}执行正则表达式匹配。

  • 我的代码中没有 range 的概念,只有日期比较。我认为行是有序的唯一地方是当我说sed时,当行比结束日期更新时退出。如果删除最终模式及其动作,代码将贯穿整个输入,但您可以放弃订购文件的要求。