我怎样才能在syslog.gz中删除,同时使用grep查找行?- 记忆

0 人关注

我写了一个程序,搜索最古老的日志,然后我想检查日志,如果有例如 "7月30日22:40 "的日志。 我想删除这些日志。 但我没有在这里或其他地方找到这样的东西。 你能帮助我吗?

var = subprocess.Popen('find /var/log/syslog* -mtime +%i' % specific_delete_range, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
out, err = var.communicate()
out = out.decode('ascii')
for line in out.split():
    firstresult.append(line)
for element in firstresult:
    with gzip.open(element, 'rb') as f:
        for line in f:
            if my_str_as_bytes in line:
                rightlines.append(line)

因此,在列表 "rightlines "中的那些行应该被删除。

1 个评论
我不确定我是否理解。如果你在其他程序访问该文件时删除行,其他程序可能会感到困惑。一般来说,我们尽量避免这样的问题:你可能想编辑一个文件的副本,然后把副本移到原文件上。
python
shell
unix
grep
gzip
Naomi
Naomi
发布于 2020-08-06
2 个回答
dash-o
dash-o
发布于 2020-08-06
0 人赞同

在文件中间 "删除行 "是不可能的。即使对普通文件可以这样做,对压缩文件也不可能这样做,因为压缩文件是由 "块 "组成的,而块很可能不在行的边界上对齐。

作为一种选择,可以考虑将留在文件中的内容提取到新的文件中,然后重命名新的文件以覆盖旧的文件。

下面的bash脚本在压缩的日志文件中寻找模式 "P",并且用一个没有模式 "P "的新文件来替换内容。

注意:该脚本不会处理未压缩的文件(与OP脚本的工作方式类似)。模式/var/log/syslog*被修改为只选择压缩文件(/var/log/syslog*.gz)。这可能需要根据压缩文件的实际后缀来调整。

days=30   # Change to whatever file age
P="Jul 30 22:40"    # Pattern to remove
for file in $(zfgrep -l "$P" $(find /var/log/syslog*.gz -mtime +$days)) ; do
    # Extract content, re-compress and overwrite old files
    zfgrep -v "$P" $file | gzip > $file.new && mv $file.new $file
    
tripleee
tripleee
发布于 2020-08-06
0 人赞同

从某种意义上说,在Python中这样做是有点疯狂的,因为用shell脚本简洁地做这件事要容易得多。 但这里有一个重构代码的方法。

一般来说,如果可以的话,你应该避免使用 subprocess.Popen() ;你的代码使用 subprocess.run() 会更容易,更习惯。 但是在这种情况下,当 find 有可能返回大量的匹配时,我们可能希望在报告文件时对它们进行处理,而不是等待子进程完成后再收集其输出。使用来自 这个Stack Overflow的答案 ,并根据实际情况进行调整。 子进程中'shell=True'的实际含义 为了避免 shell=True ,请尝试以下方法

#!/usr/bin/env python3
from subprocess import Popen, PIPE
import gzip
from tempfile import NamedTemporaryFile
import shutil
import os
with Popen(
        ['find' '/var/log', '--name=syslog*', '-mtime', '+' +  specific_delete_range],
        stdout=PIPE, bufsize=1, text=True) as p:
    for filename in p.stdout:
        filename = filename.rstrip('\n')
        temp = NamedTemporaryFile(delete=False)
        with gzip.open(filename, 'rb') as f, gzip.open(temp, 'wb') as z:
            for line in f:
                if my_str_as_bytes not in line:
                    z.write(line)
        os.unlink(filename)
        shutil.copy(temp, filename)