如何使用bash从大文本文件中删除行

for*_*own 3 bash grep awk sed

我的 CentOS 中有一个巨大的文本文件(日志文件),我想删除其中的顶部部分,每天可能有几千行。(或者可能只是分成两部分)

我搜索了这个站点,发现大多数使用 grep、sed 来删除行但输出到另一个文件。不确定是否有可能使用 shell 脚本(bash)来更新文件?代替:

sed current file > new file
cp new file > current file
Run Code Online (Sandbox Code Playgroud)

谢谢!

Ero*_*oen 5

sed --in-place $filter $file


jfg*_*956 5

没有简单的方法可以从文件的开头删除行!

即使使用sed -i,您也可以使用以下命令创建一个新文件(这>是我的提示):

> echo "Helo World" > toto
> ls -i toto
147543 toto
> sed -i -e 's/Helo/Hello/' toto
> ls -i toto
147292 toto
Run Code Online (Sandbox Code Playgroud)

请注意,inode 编号不相同。这意味着您创建了一个具有相同名称的新文件,而不是就地修改该文件。

如果您的日志文件在您执行此操作时被程序打开,这一点很重要。如果是,您将创建一个新文件,而保存该文件的程序将继续写入旧文件。为了证明这一点,让我们尝试以下操作:

for f in $(seq 1 100); do date; echo $f; sleep 1; done > file1&
ln file1 file2
sleep 5
sed -i -e '1,10d' file1
ls -l file1 file2
sleep 5
ls -l file1 file2
Run Code Online (Sandbox Code Playgroud)

第二个ls将显示相同的大小file1和不断增长的大小file2。如果我ln在执行之前没有做 a sed,原始文件将继续增长而无法通过文件系统层次结构访问。这将导致磁盘上的使用空间如 所示df但未显示du。可以在此处此处找到更多信息。

日志轮换在这里是您的朋友,但如果没有日志程序的帮助,它就无法完成。应该有办法告诉程序关闭并重新打开文件,这样新文件就会被使用,但是在sed文件开始和重新打开结束之后写入的日志可能会丢失。如果不想丢失日志,可以先复制文件,请求程序重新打开文件,然后修改复制的文件。这logrotate使您可以使用最少的脚本进行操作。

您可以在此处 (apache 1.3)此处 (apache 2.4)此处 (bind 9)阅读有关此主题的更多信息。