2012-02-10 70 views
4

下面的sed将精确输出输入。我想要做的是在第一个匹配组(\ 1)中替换所有出现的_,而不是在第二个匹配组中。这可能吗?如果只匹配某一行的匹配项,可以sed进行搜索和替换吗?

echo 'abc_foo_bar=one_two_three' | sed 's/\([^=]*\)\(=.*\)/\1\2/' 
abc_foo_bar=one_two_three 

所以,我希望的输出是:

abc-foo-bar=one_two_three 

我宁愿不诉诸awk的,因为我在做其他sed命令串过,但我如果必须的话,我会诉诸于此。

编辑:小修复到RE

+0

是您的RE真的是你想要什么?我期望'\([^ =] *])\(=。* \)'。这就是我的答案,但可以根据需要进行调整。 – 2012-02-10 13:11:09

+0

你说得对,我已经更新了这个问题来反映这一点。谢谢。 – 2012-02-10 13:21:51

回答

3

你可以这样做

$ echo 'abc_foo_bar=one_two_three' | sed 'h; s/[^=]*//; x; s/=.*//; s/_/-/g; G; s/\n//g' 
abc-foo-bar=one_two_three 
:在使用保持空间的sed
+0

我想答案应该是在保持空间弄好了,我只是没怎么看,因为我以前从来没有使用过它。谢谢:) – 2012-02-10 13:11:28

1

你可以使用awk代替sed如下:

echo 'abc_foo_bar=one_two_three' | awk -F= -vOFS== '{gsub("_", "-", $1); print $1, $2}' 

来,如预期的输出结果:

abc-foo-bar=one_two_three 
1

你可以使用ghc代替sed如下:

echo "abc_foo_bar=one_two_three" | ghc -e "getLine >>= putStrLn . uncurry (++) . (map (\x -> if x == '_' then '-' else x) *** id) . break (== '=')" 

会如预期的输出:

abc-foo-bar=one_two_three 
+0

至少它比任何'sed'可能杂牌确实更具可读性。 – 2012-02-10 13:31:43

+1

哈哈,很好。虽然要求人们安装一个Haskell编译器会让我在办公室里相当不受欢迎:) – 2012-02-10 13:38:41

1

这可能会为你工作:

echo 'abc_foo_bar=one_two_three' | 
sed 's/^/\n/;:a;s/\n\([^_=]*\)_/\1-\n/;ta;s/\n//' 
abc-foo-bar=one_two_three 

或者这:

echo 'abc_foo_bar=one_two_three' | 
sed 'h;s/=.*//;y/_/-/;G;s/\n.*=/=/' 
abc-foo-bar=one_two_three