Can sed look for and replace with a match if it matches only part of the string?

The sed below will output the input accurately. What I would like to do is replace all occurrences of _ with - in the first matching group (\ 1), but not in the second. Is it possible?

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

So, the conclusion I hope for is:

 abc-foo-bar=one_two_three 

I would prefer not to resort to awk, since I also execute a number of other sed commands, but I will resort to this if necessary.

Edit: minor fix for RE

+4
source share
4 answers

You can do this in sed using hold space:

 $ echo 'abc_foo_bar=one_two_three' | sed 'h; s/[^=]*//; x; s/=.*//; s/_/-/g; G; s/\n//g' abc-foo-bar=one_two_three 
+3
source

You can use awk instead of sed as follows:

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

The output would be as expected:

 abc-foo-bar=one_two_three 
+1
source

You can use ghc instead of sed as follows:

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

The output would be as expected:

 abc-foo-bar=one_two_three 
+1
source

This might work for you:

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

Or that:

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

Source: https://habr.com/ru/post/1395768/


All Articles