我需要使用bash脚本从一个巨大的文本文件中反复删除第一行。

现在我正在使用sed - I -e "1d" $FILE -但它需要大约一分钟的时间来删除。

有没有更有效的方法来实现这个目标?


当前回答

你可以很容易地做到这一点:

cat filename | sed 1d > filename_without_first_line

在命令行上;或者要永久删除文件的第一行,使用sed的in-place模式,并带-i标志:

sed -i 1d <filename>

其他回答

如果你想修改文件,你总是可以使用原始的ed,而不是它的流继承者sed:

ed "$FILE" <<<$'1d\nwq\n'

ed命令是最初的UNIX文本编辑器,当时还没有全屏终端,更不用说图形工作站了。ex编辑器,就是在vi中键入冒号提示符时所使用的编辑器,是ed的扩展版本,因此许多相同的命令都可以工作。虽然ed是用于交互的,但它也可以通过发送一串命令以批处理模式使用,这就是这个解决方案所做的。

序列<<<$'1d\nwq\n'利用了现代shell对here-strings(<<<)和ANSI引号($'…')的支持,将输入提供给由两行组成的ed命令:1d删除第一行,然后wq将文件写回磁盘,然后退出编辑会话。

应该显示除第一行以外的其他行:

cat textfile.txt | tail -n +2

不,这是你能得到的最高效率。您可以编写一个C程序,它可以更快地完成这项工作(更少的启动时间和处理参数),但随着文件变大,它可能会趋向于与sed相同的速度(如果需要一分钟,我就假定它们很大)。

但是你的问题和其他问题一样,都是以解决方案为前提的。如果你能详细地告诉我们你正在尝试做什么,而不是如何做,我们可能会提出一个更好的选择。

例如,如果这是一个由其他程序B处理的文件a,一种解决方案是不去掉第一行,而是修改程序B以不同的方式处理它。

假设您的所有程序都附加到这个文件A,程序B当前在删除它之前读取并处理第一行。

您可以重新设计程序B,这样它就不会试图删除第一行,而是在文件a中维护一个持久的(可能是基于文件的)偏移量,以便下次运行时,它可以查找该偏移量,处理那里的行,并更新偏移量。

然后,在一个安静的时间(午夜?),它可以对文件a进行特殊处理,删除当前处理的所有行,并将偏移量设置为0。

对于程序来说,打开并查找文件肯定比打开并重写要快。当然,这个讨论假设您可以控制程序B。我不知道是不是这样,但如果你提供进一步的信息,也许还有其他可能的解决方案。

如果您要做的是在失败后恢复,那么您可以构建一个包含迄今为止所做的工作的文件。

if [[ -f $tmpf ]] ; then
    rm -f $tmpf
fi
cat $srcf |
    while read line ; do
        # process line
        echo "$line" >> $tmpf
    done

海绵util避免了对临时文件的杂耍:

tail -n +2 "$FILE" | sponge "$FILE"