【问题标题】:Edit the first and last line of a huge file编辑大文件的第一行和最后一行
【发布时间】:2014-07-31 12:51:34
【问题描述】:

我想编辑一个非常大的文件 (~500GB) 中的第一行和最后一行。怎么能这样?例如,在第一行我有:

-flag </begin> 

我想省略“-flag”。我尝试使用 sed(如图所示)编辑第一行但我没有工作:

sed -i '1s/-flag <begin>/<begin>/g' file.txt 

【问题讨论】:

  • 你想从最后一行删除什么?

标签: linux sed large-files


【解决方案1】:

发现 sed 有 -i 选项可以更改文件。 并且您可以删除带有标志 nd 的行号 n,第一行是 1d。最后一行的 $d

删除第一行

sed -i 1d yourfile.txt

删除最后一行

sed -i '$d' yourfile.txt

更多信息在这里: https://stackoverflow.com/a/53433208/9475713

【讨论】:

    【解决方案2】:

    通常,更改文件的开头需要完全重写文件 - 原因与文件系统的工作方式有关,这些原因已得到很好的解释 here

    但有一个技巧,如果您在保持完全相同的长度的情况下重写该行:就地编辑

    执行此任务的简单命令行工具是 linux 上的 hexedit(参见其快捷方式 there)。它的速度非常快,因为只需要将更改的字节写入磁盘。但是,它要求新行具有相同数量的字符,这并不总是可行的。

    在 OP 情况下,将 -flag 替换为 5 个“空格”字符可能就足够了,但其他情况可能更难处理。

    【讨论】:

      【解决方案3】:

      我想不出一种可以就地执行此操作的方法(我很想听听!)

      几乎不是单线,但您可以尝试一下:

      # substitute the first line and exit
      sed '1s/-flag \(.*\)/\1/;q' file > new        
      # add the rest of the file (probably quicker than sed)
      tail -n +2 file >> new    
      # cut off the last line of the file
      truncate -s $(( $(stat -c "%s" new) - $(tail -n 1 new | wc -c) )) new
      # substitute the last line                             
      tail -n 1 file | sed 's/-flag \(.*\)/\1/' >> new
      

      这假设你有几个工具,比如truncate,并且你可以在你的 shell 中做算术(我的 shell 是bash)。

      truncate -s 通过获取文件总大小stat -c "%s" 与最后一行的长度(以字节为单位)之间的差值来删除最后一行。

      我不确定您要从最后一行删除什么,但我认为它与第一行相同(从行首删除 -flag)。

      欢迎提出修改建议。

      【讨论】:

      • 只有在用完全相同数量的文本替换现有文本时,才能在原地执行此操作,这样文件其余部分的偏移量不会改变。为此,您可以使用dd。由于 OP 示例正在删除文本,因此需要移动文件的整个其余部分...
      • 在最后一步替换最后一行时,文件是什么意思?
      • 对不起,我看看文件指的是什么!
      • file 是原始文件的名称,new 是新文件的名称。
      • @OlivierPons 你应该在这里使用其中一种方法stackoverflow.com/a/17794626/2088135(链接显示的答案在大文件上表现良好)
      【解决方案4】:

      如果你只想去掉第一行中的-flag(注意尾随空格):

      sed -i '1s/-flag //' file
      

      如果要完全替换第一行的内容,可以发出

      sed -i '1s/.*/new first line/' file
      

      要对最后一行做同样的事情(我提供这个作为例子,因为你没有说你想对最后一行做什么),你会这样做

      sed -i '$s/.*/new last line/' file
      

      【讨论】:

      • 由于我指定了行号,这不应该是一个快速的过程吗?但是,我可以看到 sed 在我发出命令后已经工作了一段时间。
      • 破折号在正则表达式中没有特殊含义(字符类子语言除外),因此不需要转义。
      • 文件将从头到尾处理。没有办法只重写文件的开头。
      • 感谢您的解释。我以为只会处理相应的行。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-20
      • 1970-01-01
      相关资源
      最近更新 更多