如何使用bash / sed脚本删除文本文件的第一行?

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

现在,我正在使用sed -i -e "1d" $FILE但删除它大约需要一分钟。

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


#1楼

可以就地编辑文件:只需使用perl的-i标志,如下所示:

perl -ni -e 'print unless $. == 1' filename.txt

根据您的要求,这使得第一行消失了。 Perl将需要读取和复制整个文件,但是它安排将输出保存为原始文件的名称。


#2楼

对于使用非GNU的SunOS的用户,以下代码将有所帮助:

sed '1d' test.dat > tmp.dat 

#3楼

如果您要执行的操作是在失败后恢复,则可以建立一个具有到目前为止已完成操作的文件。

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

#4楼

您可以使用-i来更新文件,而无需使用'>'运算符。 以下命令将从文件中删除第一行并将其保存到文件中。

sed -i '1d' filename

#5楼

不,这与您将要获得的效率差不多。 您可以编写一个C程序,该程序可以更快地完成工作(更少的启动时间和处理参数),但是随着文件变大,它可能趋向于与sed相同的速度(如果花一分钟,我认为它们会变大) )。

但是您的问题与其他许多问题一样面临着同样的问题,因为它以解决方案为先决条件。 如果你要告诉我们详细你想要做而不是什么 怎么样 ,我们也许能够提出更好的选择。

例如,如果这是其他程序B处理的文件A,则一种解决方案是不剥离第一行,而修改程序B以不同方式处理它。

假设您的所有程序都附加到此文件A,并且程序B当前在删除第一行之前对其进行读取和处理。

您可以重新设计程序B,以便它不会尝试删除第一行,而是在文件A中保留一个持久的(可能是基于文件的)偏移量,以便在下次运行时可以查找该偏移量,然后进行处理。那里的线,并更新偏移量。

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

程序打开并查找文件肯定比打开并重写更快。 当然,该讨论假定您具有对程序B的控制权。 我不知道是这种情况,但是如果您提供更多信息,可能还有其他可能的解决方案。


#6楼

由于听起来我无法加快删除速度,所以我认为一种好的方法可能是按以下方式批量处理文件:

While file1 not empty
  file2 = head -n1000 file1
  process file2
  sed -i -e "1000d" file1
end

这样做的缺点是,如果程序在中间被杀死(或者如果其中有一些不好的sql,导致“进程”部分死亡或锁定),则会跳过或处理两次行。

(file1包含几行sql代码)


#7楼

正如Pax所说,您可能不会比这更快。 原因是几乎没有文件系统支持从文件开头截断,因此这将是一个O( n )操作,其中n是文件的大小。 你可以做什么,虽然速度更快是覆盖具有相同的字节数(也许用空格或注释),这可能会为您取决于正是你正在尝试做的工作第一线(那是什么来着?)。


#8楼

是否会在N-1行上使用tail并将其定向到文件中,然后删除旧文件,然后将新文件重命名为旧名称呢?

如果我以编程方式执行此操作,则在读取每一行后,我将通读文件,并记住文件偏移量,因此我可以返回该位置以读取其中少一行的文件。


#9楼

试试tail

tail -n +2 "$FILE"

-nx :仅打印最后的x行。 tail -n 5将为您提供输入的最后5行。 +号可以反转参数,并使tail打印除x-1行以外的任何内容。 tail -n +1会打印整个文件, tail -n +2会打印除第一行以外的所有内容, tail -n +2

GNU的tailsed快得多。 在BSD上也可以使用tail ,并且-n +2标志在两个工具之间都一致。 有关更多信息,请参见FreeBSDOS X手册页。

不过,BSD版本可能比sed慢得多。 我想知道他们是如何做到的; tail应该只逐行读取文件,而sed相当复杂的操作,包括解释脚本,应用正则表达式等。

注意:您可能会想使用

# THIS WILL GIVE YOU AN EMPTY FILE!
tail -n +2 "$FILE" > "$FILE"

但这会给你一个空文件 。 原因是重定向( > )发生在shell调用tail之前:

  1. Shell截断文件$FILE
  2. 壳牌为tail创建新流程
  3. Shell将tail进程的标准输出重定向到$FILE
  4. tail从现在为空的$FILE读取

如果要删除文件中的第一行,则应使用:

tail -n +2 "$FILE" > "$FILE.tmp" && mv "$FILE.tmp" "$FILE"

&&将确保出现问题时不会覆盖文件。


#10楼

sponge避免了处理临时文件的需要:

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

#11楼

应该显示第一行以外的行:

cat textfile.txt | tail -n +2

#12楼

可以使用vim来做到这一点:

vim -u NONE +'1d' +'wq!' /tmp/test.txt

这应该更快,因为vim在处理时不会读取整个文件。


#13楼

如果要修改到位的文件,你总是可以使用原始ed ,而不是以S treaming接班人sed

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

ed命令是原始的UNIX文本编辑器,甚至没有全屏终端,而图形工作站则少得多。 的ex主编,最有名的是你用什么在结肠提示符下键入时vi ,是一个趋于版ed ,所以很多相同的命令工作的。 尽管ed旨在交互使用,但也可以通过向其发送一串命令而以批处理方式使用它,这是此解决方案的作用。

序列<<<$'1d\\nwq\\n'充分利用了Bash对here-string( <<< )和POSIX引号( $' ... ' )的支持,将输入提供给ed命令,该命令由两行组成: 1d其中详细eletes线1,然后wq ,其中W仪式文件回到磁盘和则q UITS编辑会话。


#14楼

您可以轻松地做到这一点:

cat filename | sed 1d > filename_without_first_line

在命令行上; 或要永久删除文件的第一行,请使用带有-i标志的sed就地模式:

sed -i 1d <filename>

#15楼

如何使用csplit?

man csplit
csplit -k file 1 '{1}'
发布了0 篇原创文章 · 获赞 1 · 访问量 5327
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 1024 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览