user2043487
user2043487

Reputation: 1

Using sed to find and replace within matched substrings

I'd like to use sed to process a property file such as:

java.home=/usr/bin/java
groovy-home=/usr/lib/groovy
workspace.home=/build/me/my-workspace

I'd like to replace the .'s and -'s with _'s but only up to the ='s token. The output would be

java_home=/usr/bin/java
groovy_home=/usr/lib/groovy
workspace_home=/build/me/my-workspace

I've tried various approaches including using addresses but I keep failing. Does anybody know how to do this?

Upvotes: 0

Views: 482

Answers (6)

Mirage
Mirage

Reputation: 31548

Other way using sed

sed -re 's/(.*)([.-])(.*)=(.*)/\1_\3=\4/g' temp.txt

Output

java_home=/usr/bin/java
groovy_home=/usr/lib/groovy
workspace_home=/build/me/my-workspace

In case there are more than .- on left hand side then this

sed -re ':a; s/^([^.-]+)([\.-])(.*)=/\1_\3=/1;t a' temp.txt

Upvotes: 0

Rob Davis
Rob Davis

Reputation: 15772

This works with any number of dots and hyphens in the line and does not require GNU sed:

sed 'h; s/.*=//; x; s/=.*//; s/[.-]/_/g; G; s/\n/=/'  < data

Here's how:

  • h: save a copy of the line in the hold space
  • s: throw away everything before the equal sign in the pattern space
  • x: swap the pattern and hold
  • s: blow away everything after the = in the pattern
  • s: replaces dots and hyphens with underscores
  • G: join the pattern and hold with a newline
  • s: replace that newline with an equal to glue it all back together

Upvotes: 0

potong
potong

Reputation: 58351

This might work for you (GNU sed):

sed -r 's/=/\n&/;h;y/-./__/;G;s/\n.*\n//' file

"You wait ages for a bus..."

Upvotes: 0

Kent
Kent

Reputation: 195029

awk makes life easier in this case:

awk -F= -vOFS="=" '{gsub(/[.-]/,"_",$1)}1' file

here you go:

kent$  echo "java.home=/usr/bin/java
groovy-home=/usr/lib/groovy
workspace.home=/build/me/my-workspace"|awk -F= -vOFS="=" '{gsub(/[.-]/,"_",$1)}1'
java_home=/usr/bin/java
groovy_home=/usr/lib/groovy
workspace_home=/build/me/my-workspace

if you really want to do with sed (gnu sed)

sed -r 's/([^=]*)(.*)/echo -n \1 \|sed -r "s:[-.]:_:g"; echo -n \2/ge' file

same example:

kent$  echo "java.home=/usr/bin/java
groovy-home=/usr/lib/groovy
workspace.home=/build/me/my-workspace"|sed -r 's/([^=]*)(.*)/echo -n \1 \|sed -r "s:[-.]:_:g"; echo -n \2/ge'
java_home=/usr/bin/java
groovy_home=/usr/lib/groovy
workspace_home=/build/me/my-workspace

Upvotes: 1

cha0site
cha0site

Reputation: 10717

What about...

$ echo foo.bar=/bla/bla-bla | sed -e 's/\([^-.]*\)[-.]\([^-.]*=.*\)/\1_\2/'
foo_bar=/bla/bla-bla

This won't work for the case where you have more than 1 dot or dash one the left, though. I'll have to think about it further.

Upvotes: 1

arutaku
arutaku

Reputation: 6087

In this case I would use AWK instead of sed:

awk -F"=" '{gsub("\\.|-","_",$1); print $1"="$2;}' <file.properties>

Output:

java_home/usr/bin/java
groovy_home/usr/lib/groovy
workspace_home/build/me/my-workspace

Upvotes: 0

Related Questions