【发布时间】:2015-09-01 12:35:35
【问题描述】:
我有大约 50 个大文本文件 (~4GB),我只需要替换这些文件前 100 行中的一个字符串。事实上,我需要的是一个 unix 命令行来查找第一个匹配项,将其替换到位并中断。
我尝试过使用 sed,但我仍在努力获得令人满意的结果。
【问题讨论】:
-
也有点类似Edit huge SQL data file。在具有 20 GiB 可用空间的机器上,该文件大约 23 GiB。
我有大约 50 个大文本文件 (~4GB),我只需要替换这些文件前 100 行中的一个字符串。事实上,我需要的是一个 unix 命令行来查找第一个匹配项,将其替换到位并中断。
我尝试过使用 sed,但我仍在努力获得令人满意的结果。
【问题讨论】:
您最多可以使用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 的变体。
【讨论】:
如果您想在不知道确切位置的情况下处理第一次出现,您可以使用ed。这是一个非常古老的行编辑器,是在内存稀缺的时候编写的。它可能比这里的 sed 效率低一点,但更简单,更健壮,因为专利不完全符合预期。
echo '/input/s/input/output/
wq' | ed file
【讨论】:
sed -i '1,100 { :a; N; $! ba; s/input/output/ }' file
:a; N; $! ba 在模式空间中追加前 100 行-i 是就地编辑q 替换后无法使用,因为它将停止打印其余行。
另外,在执行上述 sed 之前,我建议检查文件内的模式字符串以及在哪里
sed -n '/patternstring/{=;p}' file
其中 = 是打印行号(一些 grep 样式的 sed 命令)
或者如果您想在找到第一个匹配项后立即退出
sed -n '/patternstring/{=;p;q}' file
【讨论】:
'1,100 s/input/output/'