【问题标题】:Linux command to replace string in LARGE file with another stringLinux命令用另一个字符串替换LARGE文件中的字符串
【发布时间】:2010-11-17 15:56:34
【问题描述】:

我有一个在服务器上执行的巨大 SQL 文件。转储来自我的机器,其中有一些与我的机器相关的设置。所以基本上,我希望"c://temp" 的每一次出现都被"//home//some//blah" 替换

如何从命令行完成?

【问题讨论】:

  • 您的命令中缺少尾随 %。它是 s%foo%bar% 不是 s%foo%bar

标签: linux perl command-line sed awk


【解决方案1】:

sed 是大文件的不错选择。

sed -i.bak -e 's%C://temp%//home//some//blah%' large_file.sql

这是一个不错的选择,因为不会一次读取整个文件来更改它。引用手册:

流编辑器用于执行 输入的基本文本转换 流(文件或来自 管道)。虽然在某些方面相似 到允许脚本化的编辑器 编辑(如 ed),sed 由 只通过一次 输入,因此更多 高效的。但这是 sed 的能力 过滤管道中的文本 特别区别于 其他类型的编辑器。

相关手册部分为here。下面是一个小解释

-i.bak 启用就地编辑,留下带有 .bak 扩展名的备份副本

s%foo%bar% 使用 s,替换命令,它 替换第一个字符串的匹配项 第二个在 % 符号“foo”之间 字符串,“酒吧”。它通常写成 s// 但是因为你的琴弦有很多 斜线,更方便 把它们换成别的东西,这样你 避免不得不逃避它们。

例子

vinko@mithril:~$ sed -i.bak -e 's%C://temp%//home//some//blah%' a.txt vinko@mithril:~$ more a.txt //home//一些//废话 D://温度 //home//一些//废话 D://温度 vinko@mithril:~$ 更多 a.txt.bak C://温度 D://温度 C://温度 D://温度

【讨论】:

  • 您可以使用不同的字符来避免必须引用斜杠,例如 sed -e "s%C://temp%/home//some//blah%"。此外,当您确定选项时,-i 选项允许您就地保存文件。
  • 这是我正在输入的命令: sed -i.bak -e 's%C:\\temp\%/home/liveon/public_html/tmp' liveon.sql 这是我得到的错误:sed: -e expression #1, char 41: unterminated `s' command 有人吗?
  • 另外,RD,请确保正确转义反斜杠。
【解决方案2】:

只是为了完整性。使用perl就地替换。

perl -i -p -e 's{c://temp}{//home//some//blah}g' mysql.dmp

也不需要反斜杠转义。 ;)

【讨论】:

  • 请注意,如果您使用不带扩展名的-i 标志,您将获得无备份。如果您需要备份,请尝试使用-i.bak,它会进行就地编辑为您提供原始文件的备份original.bak,几乎免费。
  • 我让我的版本控制系统处理备份。
  • @Jrockway:我敢肯定,这对你来说很好,但它假设有问题的文件受版本控制,并且你知道 -i.bak 做了什么并且选择不使用它。我只希望推荐-i 开关的人能花两秒钟时间来解释-i 和-i.bak 之间的区别。如果您使用的文件不受版本控制并且您打了一个简单的错字(例如,忘记 -p 标志),那真的会很痛苦。
【解决方案3】:

试试sed?比如:

sed 's/c:\/\/temp/\/\/home\/\/some\/\/blah/' mydump.sql > fixeddump.sql

转义所有这些斜线会使这看起来很糟糕,这是一个更简单的示例,它将 foo 更改为 bar。

sed 's/foo/bar/' mydump.sql > fixeddump.sql

正如其他人所指出的,您可以选择自己的分隔符,这将阻止 leaning toothpick syndrome 在这种情况下:

sed 's|c://temp\\|home//some//blah|' mydump.sql > fixeddump.sql

sed 的聪明之处在于它在 上运行,而不是一次对一个文件进行操作,因此您可以只使用少量内存来处理大文件。

【讨论】:

  • 谢谢保罗! Intellij Idea 变得疯狂并持续了数十分钟,而使用 sed 只需 1 秒即可在我的 sql 文件中用双反斜杠替换反斜杠。
【解决方案4】:

还有一个非标准的 UNIX 实用程序 rpl,它的作用与 sed 示例的作用完全相同;但是,我不确定rpl 是否按流式运行,所以sed 可能是这里更好的选择。

【讨论】:

  • 呵呵,有机会,你是 rpl 开发者的朋友吗? :-)
  • 不,从未听说过实用程序之外的人;它在对几千个文本文件进行一次批量替换工作时派上用场,我将它保存在我的工具箱中。
  • 在这种情况下,值得说为什么你推荐它(或者你为什么可能,因为你一半收回了推荐)。也就是说,不要只是抛出一个实用程序的名称,而是请告诉我们您喜欢它的什么地方。
  • rpl 非常适合简单的替换,因为它的语法比 sed 和 find 它替换的组合更加用户友好。它还有一个简洁的试运行功能,它会告诉您它将替换什么,而无需实际进行替换。它的主要限制是它只做直接替换,没有正则表达式。
  • @Telemachus - 泰勒成功了。
【解决方案5】:

sed 命令可以做到这一点。 您可以选择不同的分隔符(在本例中为 _),而不是转义斜杠:

sed -e 's_c://temp/_/home//some//blah/_' file1.txt > file2.txt

【讨论】:

  • 你错过了最后一个下划线:“s_c://temp/_/home//some//blah_”
【解决方案6】:
perl -pi -e 's#c://temp#//home//some//blah#g' yourfilename

-p 会将此脚本视为一个循环,它将逐行读取指定的文件,运行正则表达式搜索和替换。

-i 此标志应与 -p 标志一起使用。这命令 Perl 就地编辑文件。

-e 只是表示执行这个 perl 代码。

祝你好运

【讨论】:

    【解决方案7】:

    呆呆

    awk '{gsub("c://temp","//home//some//blah")}1' file
    

    【讨论】:

      猜你喜欢
      • 2017-03-07
      • 2011-07-01
      • 2018-05-19
      • 1970-01-01
      • 2019-03-21
      • 2019-05-14
      • 2013-12-03
      • 2021-06-15
      • 2017-01-28
      相关资源
      最近更新 更多