2012-02-10 68 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