Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 无中断的tail-F_Linux_Bash_Sed - Fatal编程技术网

Linux 无中断的tail-F

Linux 无中断的tail-F,linux,bash,sed,Linux,Bash,Sed,我正在跟踪一个文件。我想在跟踪文件时删除文件中的行。我希望避免覆盖文件(截断),也希望避免用新文件替换文件,因为这很可能会弄乱/破坏tail命令的结果 目前,我尝试了两种不同的方法: 读取文件的全部内容,删除不需要的数据行,然后用比以前更少的数据写回文件。这导致从tail命令=>“文件被截断”…tail-F仍在工作,但它会记录此stderr 使用sed-i'/pattern/d'my file.txt删除文件中我不再需要的行。这导致从tail命令=>“文件被替换”(注意与上面不同)…tail-F

我正在跟踪一个文件。我想在跟踪文件时删除文件中的行。我希望避免覆盖文件(截断),也希望避免用新文件替换文件,因为这很可能会弄乱/破坏tail命令的结果

目前,我尝试了两种不同的方法:

  • 读取文件的全部内容,删除不需要的数据行,然后用比以前更少的数据写回文件。这导致从tail命令=>
    “文件被截断”
    tail-F
    仍在工作,但它会记录此stderr

  • 使用sed-i'/pattern/d'my file.txt删除文件中我不再需要的行。这导致从tail命令=>
    “文件被替换”
    (注意与上面不同)…
    tail-F
    仍在工作,但它会记录此stderr

  • 我想知道是否有一种方法可以在不截断文件或替换文件的情况下删除文件中的行,因为这似乎会让
    tail
    的生活更艰难


    我应该忽略这个标准吗?如果我忽略了stderr,我认为尾部结果会不准确。我需要尾部结果尽可能准确,因为它们正在输入一个新的程序,而不是由人读取。

    我看到的一个解决方法是:

    • 以读/写方式打开文件
    • 确定要拆下的管路
    • 与其删除换行符,不如将上一换行符+换行符的内容替换为空格字符
    更换前:

    aaaaaaa\n
    bbbbbbb\n
    ccccccc\n
    
    aaaaaaa        \n
    ccccccc\n
    
    更换后:

    aaaaaaa\n
    bbbbbbb\n
    ccccccc\n
    
    aaaaaaa        \n
    ccccccc\n
    
    从外观上看,日志已删除该行

    如果您不介意额外的空格/可以使用
    sed的//*$//g'
    执行脱机清理,那就好了,因为以读写方式打开不会更改未更改数据或文件节点的位置

    作为奖励,这是非常快的,因为即使文件很大,您也只是更改了几个字节,而不是重写整个文件

    我花了很长时间编写这个python实现,它可以工作:

    import re,os,sys
    logfile = sys.argv[1]
    regex = sys.argv[2]
    replacement_char = " "  # default: space
    if len(sys.argv)>3:
       replacement_char = sys.argv[3][0]  # first char of 3rd arg
    
    pattern = re.compile(regex)
    
    with open(logfile,"r+") as f:
        while True:
            old_offset = f.tell()
            l = f.readline()
            if not l:
                break
            if pattern.search(l):
                # match: blank the line
                new_offset = f.tell()
                if old_offset > len(os.linesep):
                    old_offset-=len(os.linesep)
                f.seek(old_offset)
                f.write(replacement_char*(new_offset-old_offset-len(os.linesep)))
    
    如何使用:

    blank.py logfile regex <optional replacement char>
    
    blank.py日志文件regex
    
    工作原理:

    • 以读/写模式打开文件
    • 线路上的回路
    • 存储当前文件偏移量
    • 读一行
    • 如果与正则表达式匹配,则获取当前偏移量,倒带到上一个文件偏移量,并写入指定的适当数量的空格/替换字符,删除上一个换行符,使空格位于有效行之后,因此视觉效果与删除该行相同
    • 由于该文件是以读/写模式打开的,因此读取该文件的外部程序(在Linux上)不会注意到更改,因为大小和索引节点没有更改:不再有来自
      tee的警告
    因为它会覆盖上一行提要,所以它只会向上一行添加空格/替换字符


    您已经注意到的唯一问题是,如果第一行匹配,那么它会在其中放入替换字符。这是唯一一次它是可见的。作为一种解决方法,您可以使用一个特殊的、不可匹配的头来启动日志文件。

    您是否考虑过重定向
    stderr
    ,即
    tail-F path 2>/dev/null
    ?我假设不可能就地编辑文件。那么sed-I就是sed-in,这似乎暴露了这样一个事实,即该文件实际上已被一个新文件替换,相当蹩脚。你真的需要编辑该文件吗?还是在跟踪时不看到“坏行”就足够了?@andreas,多个进程将跟踪该单个文件,因此该文件必须是唯一且最终的真实来源。最好是删除行,然后修改行并以某种方式将其标记为“已删除”。如果你不删除行,那么文件会变得太大。我喜欢这个,我希望它能工作!请您逐字引用您建议实际编辑该文件的sed命令好吗?好处是该文件具有相同数量的字符和行,刚才有一些是空白。这将使tail命令的使用变得更加容易!我看到的唯一问题是,我还想使用head命令读取文件的前几行。如果我有很多空格,那么前几行可能是空的。@JF,我仍然不知道该使用什么命令:“不是删除它,而是用空格字符替换以前的换行符+行的内容。”我尝试了这个答案,也只是用一个新文件替换文件,所以这对我来说不太合适。谢谢,然而,我的猜测是,当您写回文件时,它将截断整个内容并用新结果覆盖。