我需要在连续记录数据的同时从日志文件中删除/截断前N个字节。 例如nohup.out
虽然我可以像这样使用bash
截断命令。
truncate -c -s -10K my_file
。
这将截断文件末尾的最新数据。因此在这种情况下没有用。
我需要从文件的开头(包含较旧的数据)开始将其截断并保存新的文件。
我在线检查过,大部分示例都使用重定向或使用dd
,head
等写入临时文件。我需要在同一文件上内联执行此操作。
最接近的匹配是sed
,但是到目前为止,我发现了从每行中截断N个字符的示例。
例如下面将从my_file的每一行中删除10个字节。
sed -i 's/^\(.\)\{10\}//g' my_file
我正在寻找可以删除从第1行开始到第K行的前N个字节的选项,其中第N个要删除的字节结束,从而将最新数据保留在底部。
我可能可以通过一些逻辑来实现此目的,但是想知道是否有“现成的”选项可用。
有指针吗? 谢谢。
答案 0 :(得分:1)
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
答案 1 :(得分:1)
以下将打印行,直到包含第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
包含一个整数。