【问题标题】:Sed replace first occurence in place with big filesSed 用大文件替换第一次出现的地方
【发布时间】:2015-09-01 12:35:35
【问题描述】:

我有大约 50 个大文本文件 (~4GB),我只需要替换这些文件前 100 行中的一个字符串。事实上,我需要的是一个 unix 命令行来查找第一个匹配项,将其替换到位并中断。

我尝试过使用 sed,但我仍在努力获得令人满意的结果。

【问题讨论】:

标签: unix replace sed


【解决方案1】:

您最多可以使用sed 编辑第一场比赛:

sed -e '1,/pattern/{s/pattern/replace/;}'

在第 1 到 N-1 行(其中第 N 行包含模式),替换什么都不做;在第 N 行,它完成了真正的工作。此后,您不再在 1,/pattern/ 行范围内,因此没有进一步的转换。

请注意,如果第 1 行与模式匹配,这将不起作用;然后它在第 1 行和与模式匹配的下一行进行更改。至少使用 GNU sed,您可以将 1 更改为 0,这样就可以了。

printf "%s\n" pattern pattern pattern pattern |
sed -e '0,/pattern/{s/pattern/replace/;}'

但是,描述说“在前 100 行中”,而第 1 行在前 100 行中,当它出现在第 1 行时,这不是您通常描述的方式。

您可以添加-i 选项以在您测试后覆盖原始文件。注意:并非所有版本的sed 都支持-i,并且在Mac OS X 上,备份后缀是强制性的-i.bak(但可以为空:使用-i '')。相比之下,GNU sed 有一个可选的后缀,必须附加到 -i 选项。因此,-i.bak 适用于 GNU 和 Mac (BSD) sed-i 选项的其他用途特定于您正在使用的 sed 的变体。

【讨论】:

    【解决方案2】:

    如果您想在不知道确切位置的情况下处理第一次出现,您可以使用ed。这是一个非常古老的行编辑器,是在内存稀缺的时候编写的。它可能比这里的 sed 效率低一点,但更简单,更健壮,因为专利不完全符合预期。

    echo '/input/s/input/output/
    wq' | ed file
    

    【讨论】:

      【解决方案3】:
      sed -i '1,100 { :a; N; $! ba; s/input/output/ }' file
      
      • :a; N; $! ba 在模式空间中追加前 100 行
      • 所有 100 行都将被视为一个字符串。
      • 然后替换将只关注第一个匹配的模式。
      • -i 是就地编辑

      q 替换后无法使用,因为它将停止打印其余行。

      另外,在执行上述 sed 之前,我建议检查文件内的模式字符串以及在哪里

      sed -n '/patternstring/{=;p}' file
      

      其中 = 是打印行号(一些 grep 样式的 sed 命令)

      或者如果您想在找到第一个匹配项后立即退出

      sed -n '/patternstring/{=;p;q}' file
      

      【讨论】:

      • 我只是在 500 行输入上尝试过这个,它没有任何效果。这很奇怪,因为我期待完全不同的故障模式。
      • 让我在实践中检查一下,需要更多内容 + 追加 100 行
      • 现在应该可以了,我加了$!这将永远是正确的,所以前 100 行将被追加
      • 不,它只是在原地编辑前一百行,其余部分保持不变,你不需要那么多花哨的东西。只需'1,100 s/input/output/'
      • 如果字符串不止一次出现,它将反映在所有 100 行中,我的解决方案仅适用于第一个匹配的输入字符串
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-27
      • 2020-12-09
      • 1970-01-01
      • 2015-05-30
      • 1970-01-01
      相关资源
      最近更新 更多