我希望有人可以帮我解决问题。我发现很多关于用sed读取文件的主题,但没有什么适合我的情况。也许有人知道以下情况的解决方案:
我有一个记录器,可以创建一个定义大小的文件(在我的情况下为5MB)。记录器像环形缓冲区一样使用该文件,并将记录器信息写入该文件。记录器当然是从第1行开始,用eof用结尾标记结束。在十六进制编辑器中,它看起来像这样:
0d 3c 3c 3c 45 4f 46 3e 3e 3e 0d 20 20 20 20 20 .<<<EOF>>>.
现在我有两种情况,一种是简单的,一种是复杂的:
我需要从头到尾打印标识符。
最美的解决方案是识别EOF后是否为初始值(0x20),然后从第1行打印到EOF。如果在行结束标识符之后有值,则在EOF之后读取所有文件大小,然后从第一行读取到EOF标识符。这应该打印出这个“环形缓冲区”的所有行。这样的事情可能吗?
要解决(1)我尝试了一些sed
命令,例如:
sed -e '1,$p' test.log > result.txt
- &GT;目标:打印从第1行到EOF模式的所有内容,但两个文件大小相同(在我的情况下为5MB)。看起来$ p指的是文件的真实结尾而不是EOF模式。
sed -e '/EOF/,$d' test.log > result.txt
- &GT;目标:在EOF模式之前打印所有内容,但result.txt的大小为0。
任何人都可以提供任何解决方案或解决方案吗?
答案 0 :(得分:0)
使用sed
,我认为您需要两个命令(以及对文件的两次扫描):
logfile="…some-name…"
eofmark="<<<EOF>>>"
sed -n "/$eofmark/,\$ { /$eofmark/d; p; }" $logfile # Read the tail material
sed -n "1,/$eofmark/ { /$eofmark/d; p; }" $logfile # Read the head material
使用perl
或awk
,您可以将整个文件啜饮到内存中,然后打印尾部,然后打印头部。例如,在awk
:
logfile="…some-name…"
eofmark="<<<EOF>>>"
awk "/$eofmark/"' {eofline = NR}
{line[NR] = $0}
END { for (i = eofline+1; i <= NR; i++) print line[i]
for (i = 1; i < eofline; i++) print line[i]
}' $logfile
这是可行的,因为将5 MiB文件读入内存不会对具有千兆字节主内存的机器造成压力。如果文件本身是千兆字节的数据,你可以三思而后行将其篡改到内存中,虽然扫描它两次也会很痛苦。