我想使用sed来缩短包含以日期开头的行的日志:
2017-07-26T01:01:01 236
2017-07-27T01:02:01 236
2017-07-27T01:02:51 236
2017-07-27T01:03:01 236
2017-07-28T01:01:01 236
2017-09-07T09:05:18 236
2017-09-07T10:22:10 239
(不,logrotate不会这样做)。我知道我可以使用
sed -i '0,/^2017-07-27/d' filename
删除第一个(2017-07-27)之前的所有行(就地)和第一个行,但如果文件不包含这样的行,或只有一行这样,sed将删除所有行。如果找不到模式,我不想做任何事。
我也想删除。
如果模式永远不匹配,如何防止sed删除所有行? 是否有更好的方法来实现这一目标?
答案 0 :(得分:0)
永不言败。
我们可以使用sed保留空间来收集所需的输出。如果我们将第一行与日期匹配,我们将丢弃保留空间中的累积内容,然后开始将这些行收集到保留空间中。在文件末尾,我们打印出保留空间的内容。
整个文件可能会以保留空间结尾。我想一旦找到匹配项,我们就可以直接开始打印每一行,而不是累积到保留空间……也许。但是,如果没有匹配项,我们仍然必须将整个文件累积在保留空间中-因为可能在最后一行存在匹配项,因此我们必须丢弃所有内容。但是我对此很满意。
我略微更改了示例输入,以使我在开发sed脚本时更容易查看哪些行。
bjb@rhino:~$ cat /tmp/sed.txt
2017-07-26T01:01:01 231
2017-07-27T01:02:01 232
2017-07-27T01:02:51 233
2017-07-27T01:03:01 234
2017-07-28T01:01:01 235
2017-09-07T09:05:18 236
2017-09-07T10:22:10 237
bjb@rhino:~$ sed -n ':begin H;/^2017-07-27/{s/^.*$//;x;s/^.*$//;n;b middle};$ b end;n;b begin;:middle H;$ b end;n;b middle;:end x;p;q' /tmp/sed.txt
2017-07-27T01:02:51 233
2017-07-27T01:03:01 234
2017-07-28T01:01:01 235
2017-09-07T09:05:18 236
2017-09-07T10:22:10 237
bjb@rhino:~$ sed -n ':begin H;/^fluffallaa/{s/^.*$//;x;s/^.*$//;n;b middle};$ b end;n;b begin;:middle H;$ b end;n;b middle;:end x;p;q' /tmp/sed.txt
2017-07-26T01:01:01 231
2017-07-27T01:02:01 232
2017-07-27T01:02:51 233
2017-07-27T01:03:01 234
2017-07-28T01:01:01 235
2017-09-07T09:05:18 236
2017-09-07T10:22:10 237
bjb@rhino:~$