2010-05-14 255 views
2

我试图用sed来替换字符串中的空白字符。例如,给定线:在字符串中删除SED空白字符

var test = 'Some test text here.'; 

我想:

var test = 'Sometesttexthere.'; 

我尝试使用(\x27匹配'):

sed 's|\x27\([^\x27[:space:]]*\)[[:space:]]|\x27\1|g 

,但只是给

var test = 'Sometest text here.'; 

任何想法?

回答

1

这是一个更复杂的sed脚本,但它没有循环。你知道的,只是不同的缘故:

sed 'h;s/[^\x27]*\x27\(.*\)/\n\x27\1/;s/ //g;x;s/\([^\x27]*\).*/\1/;G;s/\n//g' 

这使得字符串的副本,打出一个(这将成为下半年)的第一单引号丢弃上半年,替换所有的空格下半部分交换副本,将另一部分副本拆分,丢弃后半部分,将它们合并回去,并删除用于拆分的新行和由G命令添加的新行。

编辑:

为了选择特定行进行操作,您可以使用一些选择标准。在这里,我指定的行必须包含一个等号和至少两个单引号:

sed '/.*=.*\x27.*\x27.*/ {h;s/[^\x27]*\x27\(.*\)/\n\x27\1/;s/ //g;x;s/\([^\x27]*\).*/\1/;G;s/\n//g}' 

你可以使用任何正则表达式的作品最好的,包括并适当地排除了您的需求。

+0

好的解决方案。它似乎是O(n)而不是我的O(n^2)[Shlemiel画家解决方案](http://en.wikipedia.org/wiki/Schlemiel_the_Painter%27s_algorithm),但这个事实可能与输入长度在手边。 – 2010-05-15 07:33:36

+0

你的sed(正则表达式)技能很明显超过了我的。很好的解决方案。我想我应该提到的一件事是,并非每一行都有一个'。你的解决方案完美适用于那些行。那些没有'最终得到复制。例如,一行var x = 2;将结束为var x = 2; var x = 2; – blazeprogrammer 2010-05-17 15:01:39

+0

对于任何有兴趣的人来说,这个解决方案比接受的解决方案要快得多,主要的区别在于,这个解决方案并不能完全按照需要(我的错,而不是响应者的)工作。在我的测试文件中,这个解决方案需要0.06s,而接受的解决方案需要19.3s。 – blazeprogrammer 2010-05-17 15:24:10

0

您的命令行有两个问题:

  • 首先,有一个失踪\[^后。

  • 其次,即使使用g修饰符,也只会删除第一个空格。为什么?因为该修饰符导致在同一行内替换连续匹配。它不是而是从头开始重新扫描整行。但这是必需的,因为你的匹配是锚定在字符串文字的最初'

来解决这个问题最显而易见的方法是使用一个环,由一个条件跳转实现(跳转与tLabel:Label; t跳转如果因为具有t上次测试匹配的至少一个s)。

这是最简单的一个sed脚本(和你没有逃跑的'),像这样:

:a 
s|'\([^'[:space:]]*\)[[:space:]]|'\1| 
ta 

但是这是可以做到一个命令提示符。确切的语法可能取决于您的sed的香味,适合矿井(在Windows超级SED)被调用,像这样:

sed -e ":a" -e "s|\x27\([^\x27[:space:]]*\)[[:space:]]|\x27\1|;ta" 

您需要两个单独的脚本表情,因为标签:a上延伸直至表达式结束。

+0

使用GNU'sed',分号结束标签。 – 2010-05-14 22:39:20

+0

@丹尼斯:的确,现在我尝试过了,它也适用于超级sed。好像我之前使用过另一个版本的sed,它不支持它,并且从来不打扰再次检查。 – 2010-05-15 06:58:25

+0

该解决方案确实按照需要工作。正如你在上面的评论中指出的那样,这不是最有效的。这与我的输入长度有关,但对于我的应用程序来说,它足够好。谢谢。 – blazeprogrammer 2010-05-17 15:07:10