如何从日志文件中删除部分?


18

我有一个8 Gb日志文件(Rails生产日志)。我需要在某些日期(行)之间进行剪切。我可以使用哪个命令来执行此操作?


1
大家好,这个问题是关于一个文件的,所以它是“事前准备!”。时间很重要...我已经在一个8GB的真实文件中测试了喜欢的sed脚本,该文件包含85904064行(每行100个字符)。我喜欢sed,但就目前情况而言,sed脚本每次都会扫描整个文件。这使得它的平均速度是找到时退出的awk脚本的两倍...我认为(?)sed脚本可能只需要aq而不是d作为第二个表达式...测试结果在这里:粘贴.ubuntu.com / 573477 ..另外,它无法产生正确的输出。
Peter.O 2011年

asoundmove的新sed版本已解决了速度问题,现在它与awks的速度相匹配。现在,新的versin可以正确输出数据了……有关更多详细信息,请参见他的评论。
Peter.O 2011年

我只是注意到您说的是“剪切”(通常表示删除)...您是真的意思是“剪切”,还是意思是“复制”?....如果您的意思是“删节”,那么sed就很容易做到。
Peter.O 2011年

Answers:


12

就像是

sed '1,/last date prior to chunk/d;/first date after chunk/,$d' logfile | tee cut-log | less

tee cut-log使您可以在屏幕上看到文件中正在存储的内容cut-log

编辑:

为了满足fred.bear的严格标准,这是一个sed解决方案(尽管可以说awk解决方案更漂亮):

b=BB; e=EE ;echo -e "AA\nAA\nBB\nBB\nCC\nCC\nDD\nDD\nEE\nEE\nFF\nFF" | sed -n ":b;/$b/b p;n;b b;:p;p;n;/$e/b e;b p;:e;p;n;/$e/b e;q"


3
@dogbane:是的,是的。编辑。我确定您有时编写的代码少于最佳代码,是否值得这么刻薄的评论?
asoundmove 2011年

1
注意:如果有多个具有相同日期的连续“ first-date”行,则除了第一个以外的所有行都不会被删除,并将被引入到输出中……只是需要注意的一点……(取决于情况)
Peter.O 2011年

1
...但是,即使我赞成++,但我认为这项工作超出了自己的极限,除了个人工具之外。这是sed在这种情况下的主要问题(您,我..我设法让sed做与您相同的事情..它也跑了1%以内。..回到主要问题..(不适用于awk).... Bug(不可修复):对于在日志范围内有效但在日志中实际不存在的日期,在第一个参数的情况下,将导致sed不打印任何内容,在第二个参数的情况下,sed将打印所有内容第一次约会之后!...更多...
Peter.O 2011年

1
另一个可修复的错误:是它当前匹配任何行中的日期,包括数据属性,但这只是一个正则表达式调整。对于任何想要使用它的人,也许您可​​以评论说args现在指的是第一个和最后的日期范围(不是-1和+1)..最后..我的“确切标准”不是我的。我只是发问者请求的使者...用户注意到它是否按请求工作。.这对我来说是一个很大的问题..我学到很多东西:) ...要知道它sed可以匹配awk速度,实际上速度要快一些。
Peter.O 2011年

6

要打印介于FOO和BAR之间的所有内容,请尝试:

$ sed -n '/FOO/,/BAR/p' file.txt

1
注意:这只会打印一系列连续BARS的第一个BAR ...
Peter.O 2011年

另一个注意事项...如果数据中不存在任何日期,则是一个大问题。如果不存在最后一个日期,sed将继续输出行,直到到达EOF。
Peter.O 2011年

5

这将完成您想要的操作...显示
包括和不包括参数日期。

# set Test args
set  2011-02-24  2011-02-26  "junk"

from="$1"
till="$2"
file="$3"

# EITHER ====                              +++++++++  
# Ouptut lines between two parameter dates INCLUDING the parameter dates
  awk -v from=$from -v till=$till '
    ($2 >= from) && ($2 <= till) { print $0 ; next }
    ($2 > till) { exit }' "$file"

# OR ========                              ---------
# Ouptut lines between two parameter dates EXCLUDING the parameter dates
  awk -v from=$from -v till=$till '
    ($2 > from) && ($2 < till) { print $0 ; next }
    ($2 >= till) { exit }' "$file"

它测试字段2中的(排序)日期。这是测试数据的示例

    98  2011-02-05 xxxx
    99  2011-02-05 xxxx
   100  2011-02-06 xxxx
   101  2011-02-06 xxxx

这是测试数据生成器


我会这样写(例如第一个): awk -v from="$from" -v till="$till" '($2 >= from) { if ($2 <= till) { print } else { exit }' "$file"
asoundmove

@asoundmove:是的,这看起来可能更好,并且绝对是更传统的方法,但是实际上,它的执行时间仅是总共 1条额外if语句的持续时间(甚至每行1条)。逻辑流程实际上是相同的,并且运行时间的差异将以纳秒为单位进行计数。...我不使用“ else”的唯一原因是这实际上是我的第一个脚本(除了一天4年之外之前,当我玩一些示例时)...,这是我发现的第一个可行的分支机制...(并且如上所述。它的运行速度同样快。)。我通常使用Tryawksedq
Peter.O,2011年

我不知道您在这种方法中给文本文件的名称和位置在哪里?有人可以帮助我了解我的愚蠢吗
盖尔斯(Giles)

4

如果您的日志文件中具有这种格式的日期YYYY-MM-DD,那么要查找所有表示2011-02-10的条目,可以执行以下操作:

grep 2011-02-10 log_file

现在,假设您要查找2011-02-10和2011-02-11的条目,请再次使用grep但具有多种模式:

grep -E '2011-02-10|2011-02-11' log_file

好。它按“广告宣传”的方式工作:) ...但是,grep即使日期范围在文件的开头,它也会搜索整个文件。与“范围内最后一个项目退出”相比,平均而言,这将使搜索时间增加一倍...我只是不愿意提及这一点,因为问题“您的grep时间结果几乎与此处的sed示例相同(1分钟58秒)。这是我的时间测试结果的链接:paste.ubuntu.com/573477
Peter.O 2011年

1

使用这种大小的文件总是很困难。

一种前进的方式可能是将此文件拆分为几个小文件,为此可以使用split命令。

split -d -l 50000 ToBigFile.data file_

即使将其拆分,您仍然可以使用该文件,就像使用bash for loop一样

for f in `ls file_*`; do cat $f; done;

但是,您可以使用倒置的grep代替猫,以摆脱不需要的数据,这与此无关。(或您需要的一种改进)。

此时,您将只处理许多较小的文件,而上面提到的其他命令将对许多较小的文件起作用。

完成后,您可以使用第二个for循环来再次构建新的较小文件。

for f in `ls file_*`; do cat $f >> NewFile.data ; done;

更新 由于我们开始将数据拆分为多个文件,因此硬盘驱动器将需要大量工作,这需要时间。(这个问题显然是5分钟)。

另一方面,下一步可能会更快。

因此,对于简单的grep,awk,sed操作,此方法可能毫无意义,但是如果搜索模式变得更加复杂,它可能会变得更快。


3
Johanm,在我的计算机上搜索一个8 GB的日志文件平均需要awk并仅花费s分钟,而在同一台计算机上,仅初始文件的拆分就需要4分43秒... :)
Peter.O

假设您可以将较小的文件的awk和sed时间减少50%。然后,在获得总时间之前,我们仍然需要执行10次以上的操作...因此,对于一些回归,也许文件分割不是最好的主意...
Johan

awk脚本可以(轻松地)修改为一次将10个不同的搜索结果输出到10个文件..,但这会减慢实际输出报告时的读取速度……Sed也可以这样做,但是正如我'在asoundmove的评论中已经提到,如果特定日期/时间在日志中没有任何记录(例如,您按小时搜索),则sed将会失败。我经常使用sed,它非常有用,但是它有局限...这是有关何时使用sed和awk的sed常见问题。.我不一定全部同意,但我可以理解它们的意思... sed.sourceforge.net/sedfaq6.html
彼得。 Ø

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.