2010-01-29 106 views
9

我已经通过了sed one liners但我的目标仍然有问题。我想要替换所有行上匹配的字符串,但第一次出现一行。我的具体用法是:已将sed替换为字符串,但SKIP首次出现

$ echo 'cd /Users/joeuser/bump bonding/initial trials' | sed <<MAGIC HAPPENS> 
cd /Users/joeuser/bump\ bonding/initial\ trials 

线取代了空间bump bonding与斜线空间bump\ bonding这样我就可以执行下面这行(因为当空间没有逃过我就不能cd到它)。

更新:我解决了这个只要使用单引号和输出

cd 'blah blah/thing/another space/' 

,然后使用source要执行的命令。但它没有回答我的问题。我仍然很好奇......你会如何使用sed来修复它?

回答

9

可避免与gñ

问题

全部替换,然后撤消第一个:

sed -e 's/ /\\ /g' -e 's/\\//1' 

下面是其使用t分支如果取代的命令的另一种方法:

sed ':a;s/\([^ ]* .*[^\\]\) \(.*\)/\1\\ \2/;ta' 

具有留在输入现有反斜杠空间序列完整的优点。

+0

你的第一个答案看起来是通用的解决方案。随着一点点阅读,-e国旗似乎是我真正想要的。 – physicsmichael

8
s/ /\\ /2g 

2规定,第二个应该适用,而g规定,所有剩下的应该施加太大。 (这可能仅适用于GNU sed的。据公开组基本规范 “If both g and n are specified, the results are unspecified.”)

+0

你对GNU sed是正确的。在我的Mac上不起作用。但是,这正是我期待的那种优雅的解决方案。 – physicsmichael

+1

@physicsmichael你可以用'brew install gsed'在Mac上安装GNU sed。安装完成后,您可以输入命令为'/ usr/local/bin/gsed'而不是'sed'。 – stacko

1

用awk

$ echo cd 'blah blah/thing/another space/' | awk '{for(i=2;i<NF;i++) $i=$i"\\"}1' 
cd blah\ blah/thing/another\ space/ 

$ echo 'cd /Users/joeuser/bump bonding/initial trials' | awk '{for(i=2;i<NF;i++) $i=$i"\\"}1' 
cd /Users/joeuser/bump\ bonding/initial\ trials