从进程主动写入的 bash 内联文件开头删除前 N 个字节/行

  • 本文关键字:删除 开头 字节 文件 进程 bash bash sed
  • 更新时间 :
  • 英文 :


我需要在连续记录数据时从日志文件中删除/截断前 N 个字节。 例如 Nohup.out

虽然我可以像这样使用bash截断命令。

truncate -c -s -10K my_file.

这将截断文件末尾的最新数据。所以在这种情况下没有用。

我需要从文件开头截断文件(具有较旧数据(并保留新文件。

我在网上检查了一下,大多数示例都是使用重定向或使用ddhead等写入临时文件。我需要在同一个文件上内联执行此操作。

最接近的匹配是sed,但到目前为止,我找到了从每行截断 N 个字符的示例。 例如,下面将从my_file的每一行中删除 10 个字节。

sed -i 's/^(.){10}//g' my_file

我正在寻找可以删除从第一行开始的前 N 个字节并在第 N 个字节结束的第 N 行结束以进行删除的选项,从而在底部保留最新数据。

我可能可以编造一些逻辑来实现这一点,但想知道是否有"现成"选项可用。

有什么指示吗? 谢谢。

以下内容将打印行,直到包含第 N 个字节的行:

awk -v n="$n" 'c>=n{exit} {c+=length()+1} 1'

其中 shell 变量$n包含对您很重要的字节数。+1在那里,以便包含换行符。如果您没有单字符换行符,请进行调整以适应,或者改用length(ORS)

请注意,这不会处理请求中不可能的部分,即在另一个进程打开文件进行写入时更改文件。

为了实现与此相反的结果 - 也就是说,打印从第 N 个字节开始的每一行,我们需要一些稍微不同的东西:

awk -v n="$n" 'c>=n{p=1} {c+=length()+1} p'

这将设置一个信号量,p,一旦看到足够的字符,然后打印信号量是否计算为 true。

性能低得多的等效仅 bash 版本可能如下所示:

c=0; p=0
while read; do
((c>=n)) && p=1
((c+=${#REPLY}+1))
((p)) && echo "$REPLY"
done

您可以将其用作管道,或使用输入重定向来读取文件。它还假定$n包含一个整数。

perl -i -pe 'BEGIN{$x=100} {if ($x > 0) {$x -= length$_; s/^.*r?n?//;}}' file

其中 x 是要从文件开头修剪的字符数。 如果这不一样,我认为图书馆可能是必要的。

它的工作原理是在搜索时简单地倒计时,并用任何内容替换整行。 然后,它会停止进一步处理。 这将重写整个文件,并且可能会有一些实用程序以更聪明的方式执行此操作。

要使其可配置,请使用-s后跟---x=100(通过 bash 设置$x(:

perl -i -spe 'if ($x > 0) {$x -= length$_; s/^.*r?n?//;}' -- -x=100 file

最新更新