2009-08-07 229 views
8

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

这怎么可以从命令行完成?

+0

你缺少你的命令尾随%。这是s%foo%bar%not s%foo%bar – 2009-08-07 12:27:40

回答

29

sed是大文件的不错选择。

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

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

甲流编辑器用于对输入 流(从一个 管道文件或输入)执行 基本文本转换。尽管在某些方面 与允许脚本编辑 编辑(例如编辑)的编辑器相似,但sed作品 仅输入一个通过 输入,并且因此更有效地是 。但它是sed在流水线中过滤文本的能力,其中 特别将其与 区别于其他类型的编辑器。

相关的说明书部分是here。一个小的解释如下

-i.bak能够就地编辑留下一个备份副本.bak扩展

S%FOO%栏中%用途秒,替换命令,第一串的其中 代用品比赛 位于%符号'foo'之间,用于第二个 字符串'bar'。通常写成s // ,但由于您的字符串有大量的斜杠 ,因此更方便 将它们更改为其他内容,以便您避免必须转义它们。

 
[email protected]:~$ sed -i.bak -e 's%C://temp%//home//some//blah%' a.txt 
[email protected]:~$ more a.txt 
//home//some//blah 
D://temp 
//home//some//blah 
D://temp 
[email protected]:~$ more a.txt.bak 
C://temp 
D://temp 
C://temp 
D://temp 
+2

您可以使用不同的字符来避免引用斜线,例如sed -e“s%C:// temp%/ home // some //嗒嗒%”。 此外,-i选项允许您在确定选项时将文件保存在原位。 – dalloliogm 2009-08-07 10:59:06

+0

这是我输入的命令: sed -i.bak -e's%C:\\ temp \%/ home/liveon/public_html/tmp'liveon.sql 这是我的错误得到: sed:-e表达式#1,字符41:未终止的's'命令 任何人? – coderama 2009-08-07 11:45:44

+0

你错过了最后的%,命令是%foo%bar% – 2009-08-07 11:51:16

1

sed该命令可以做到这一点。 而不是逃避斜线,您可以选择不同的分隔符(_在这种情况下):

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

你错过了最后一个下划线:“s_c:// temp/_/home // some // blah_” – dalloliogm 2009-08-07 11:01:40

+0

谢谢!现在已修好。 – stefanw 2009-08-07 11:03:27

4

尝试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的巧妙的事情是,它在而操作而不是一个文件,因此您只能使用适量的内存来处理大文件。

+0

谢谢Paul! Intellij Idea变得疯狂并且做了几十分钟,而使用sed则只需1秒,在我的sql文件中用双反斜杠替换反斜杠。 – gumkins 2013-10-21 15:10:39

12

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

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

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

+10

请注意,如果您使用'-i'标志而没有扩展名,则会得到*无备份*。如果你想备份,可以尝试使用'-i.bak'来执行就地编辑*和*将原始文件备份为'original.bak',几乎免费。 – Telemachus 2009-08-07 14:15:21

+0

我让版本控制系统处理备份。 – jrockway 2009-08-08 02:53:33

+3

@Jrockway:我相信这对你很可爱,但它假定有问题的文件受版本控制,并且你知道-i.bak做了什么并且选择不使用它。我只希望那些推荐-i开关的人花两秒钟来解释-i和-i.bak之间的区别。如果您使用的文件不受版本控制,并且输入了简单的错字(例如,忘记-p标志),那么这将非常不利。 – Telemachus 2009-08-08 11:49:04

3

还有一个非标准的UNIX实用程序rpl,它与sed的例子完全相同;然而,我不确定rpl是否可以顺利运行,因此sed可能是更好的选择。

+0

嘿,每次机会,你是rpl开发者的朋友吗?:-) – 2009-08-07 11:22:48

+0

不,从来没有听说过util之外的人;它可以在数千个文本文件上执行一次批量替换作业,并且保存在我的工具箱中。 – 2009-08-07 12:46:01

+0

值得一提的是,为什么*你在这种情况下推荐它(或者为什么你可能,因为你收回了一半的建议)。也就是说,不要只是提供实用程序的名称,请告诉我们您喜欢它的方式。 – Telemachus 2009-08-07 14:18:29

1
perl -pi -e 's#c://temp#//home//some//blah#g' yourfilename 

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

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

-e只是表示执行此Perl代码。

好运

+0

感谢您的解释 – 2017-07-05 02:33:32

1

GAWK

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