【问题标题】:Append to the top of a large file: bash追加到大文件的顶部:bash
【发布时间】:2013-02-08 13:49:11
【问题描述】:

我有一个将近 3 GB 的文件,我想在其顶部添加两行。每次我尝试手动添加这些行时,vim 和 vi 都会在保存时冻结(我让它们每个尝试保存大约 10 分钟)。我希望有一种方法可以追加到顶部,就像追加到文件底部一样。到目前为止,我看到的唯一内容包括一个临时文件,由于文件大小,我觉得它会很慢。 我希望是这样的:

grep -top lineIwant >> fileIwant

有人知道追加到文件顶部的好方法吗?

【问题讨论】:

  • 回复:“到目前为止,我看到的唯一内容包括一个临时文件,由于文件大小,我觉得它会很慢”:您需要读取整个文件,然后写入无论如何,一切都结束了,因为您正在将每个字节“移动”到文件中的新位置。所以你真的不如创建一个临时文件。
  • “追加到顶部”通常称为“前置”,还有其他几个questions on this topic

标签: bash grep append


【解决方案1】:

试试

cat file_with_new_lines file > newfile

【讨论】:

    【解决方案2】:

    我做了一些基准测试来比较使用 sed 和就地编辑(建议 here)和 cat(建议 here)。

    ~3GB bigfile 用点填充:

    $ head -n3 bigfile
    ................................................................................
    ................................................................................
    ................................................................................
    
    $ du -b bigfile
    3025635308      bigfile
    

    文件 newlinesbigfile 上插入两行:

    $ cat newlines
    some data
    some other data
    
    $ du -b newlines
    26      newlines
    

    使用dumbbench v0.08 对结果进行基准测试:

    $ dumbbench -- sh -c "cat newlines bigfile > bigfile.new"
    cmd: Ran 21 iterations (0 outliers).
    cmd: Rounded run time per iteration: 2.2107e+01 +/- 5.9e-02 (0.3%)
    

    sed 带重定向:

    $ dumbbench -- sh -c "sed '1i some data\nsome other data' bigfile > bigfile.new"
    cmd: Ran 23 iterations (3 outliers).
    cmd: Rounded run time per iteration: 2.4714e+01 +/- 5.3e-02 (0.2%)
    

    sed 就地编辑:

    $ dumbbench -- sh -c "sed -i '1i some data\nsome other data' bigfile"
    cmd: Ran 27 iterations (7 outliers).
    cmd: Rounded run time per iteration: 4.464e+01 +/- 1.9e-01 (0.4%)
    

    所以 sed 在对大文件进行就地编辑时似乎要慢得多(80.6%),这可能是由于之后将中间临时文件移动到了原始文件的位置。使用 I/O 重定向 sed 仅比 cat 慢 11.8%。

    根据这些结果,我将按照this answer 中的建议使用 cat

    【讨论】:

      【解决方案3】:

      尝试这样做:

      使用

      sed -i '1i NewLine' file
      

      或者使用

      ed -s file <<EOF
      1i
      NewLine
      .
      w
      q
      EOF
      

      【讨论】:

      • 这是解决问题的正确方法。添加 -i 以编辑文件。 sed -i '1i newline' /path/to/file
      • OP 注意:这仍然使用一个临时文件,但它至少对你隐藏了细节。不过,它不会更快。
      【解决方案4】:

      这种操作的速度很大程度上取决于底层的file system。据我所知,没有针对此特定操作优化的 FS。大多数 FS 使用完整的磁盘块来组织文件,除了最后一个,它可能在文件末尾部分使用。实际上,大小为N 的文件将占用N/S 块,其中S 是块大小,并且文件的剩余部分再占用一个块(大小为N%S% 是余数运算符),如果N 不能被S 整除。

      通常,这些块由它们在磁盘(或分区)上的索引引用,这些索引存储在 FS 元数据中,附加到分配它们的文件条目中。

      从该描述中,您可以看到,只需使用文件使用的新块列表更新元数据,就可以预先添加大小为块大小倍数的内容。但是,如果该前置内容没有完全填充多个块,则现有数据将不得不移动超出的数量。

      某些 FS 可能会实现在文件已使用块的列表中(不仅作为最后一个条目)有部分使用块的可能性,但这并不是一件容易的事。

      有关详细信息,请参阅这些其他 SO 问题:

      在更高级别上,即使 FS 驱动程序支持该操作,程序仍然有可能不使用该功能。

      对于您要解决的那个问题的实例,最好的方法可能是一个能够catening 新内容和现有内容到新文件的程序。

      【讨论】:

      • 我想我的回答对你的问题没有多大用处,但它可能有助于理解症状背后的原因。
      【解决方案5】:
        cat file
      
         Unix
         linux   
      

      使用命令同时追加到文件的两行

      sed -i '1a C \n java ' 文件

       cat file
         Unix
         C
         java
         Linux
      

      你想插入意味着使用 i 和替换意味着使用 c

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-08
        • 2013-02-16
        • 2017-03-18
        • 2017-03-18
        • 1970-01-01
        • 2021-07-05
        • 2015-09-26
        相关资源
        最近更新 更多