PoVa
PoVa

Reputation: 1043

Uncommenting code with sed

I'm writing a script that would uncomment a few lines of code from a file. This is what I'm trying to uncomment:

#export PATH="$HOME/.rbenv/bin:$PATH"
#eval "$(rbenv init -)"

So I did my research and found this command that does what I'm looking for:

sed -i '/<pattern>/s/^#//g' file

So how would I adjust it to do what I'm looking for? I've tried pasting the text inside the command, did my best to escape the all the quotes, but it didn't seem to work.

Upvotes: 0

Views: 410

Answers (3)

Ed Morton
Ed Morton

Reputation: 203995

To do this job robustly just use awk with string operations. Given these input files:

$ cat file1
#export PATH="$HOME/.rbenv/bin:$PATH"
#eval "$(rbenv init -)"

$ cat file2
This is what I'm trying to uncomment:

#export PATH="$HOME/.rbenv/bin:$PATH"
#eval "$(rbenv init -)"

So I did my research and found this command that does what I'm looking for

This is all you need:

$ awk 'NR==FNR{a[$0];next} $0 in a{sub(/./,"")} 1' file1 file2
This is what I'm trying to uncomment:

export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"

So I did my research and found this command that does what I'm looking for

or if the target strings could appear mid-line instead of always as the whole line:

$ awk 'NR==FNR{a[$0];next} {for (i in a) if (s=index($0,i)) $0=substr($0,1,s-1) substr($0,s+1)} 1' file1 file2
This is what I'm trying to uncomment:

export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"

So I did my research and found this command that does what I'm looking for

The above will work no matter what characters the target strings contain.

Upvotes: 0

chepner
chepner

Reputation: 531808

Comments are for comments, not flow control.

Instead of trying to modify the file to toggle those lines, control their execution via an environment variable.

if [[ -v enable_ruby ]]; then
  export PATH="$HOME/.rbenv/bin:$PATH"
  eval "$(rbenv init -)"
fi

Now, if the variable enable_ruby is set to any value in the environment, PATH will be modified and ruby configured. Otherwise, those two lines are ignored.

$ bash myScript                # Don't do the ruby stuff
$ enable_ruby=1 bash myScript  # Do the ruby stuff
$ export enable_ruby=          # The empty string is sufficient
$ bash myScript                # Do the ruby stuff
$ unset enable_ruby
$ bash myScript                # Don't do the ruby stuff

Upvotes: 4

that other guy
that other guy

Reputation: 123560

You have to carefully and laboriously escape your pattern for sed as @Thomas Kühn points out.

The alternative to work smarter, not harder, and see if you can mark up the lines beforehand:

#export PATH="$HOME/.rbenv/bin:$PATH"   # setrbpath
#eval "$(rbenv init -)"                 # runrbinit

Now you can just sed -i -e '/setrbpath/s/^#//' file and it'll be stable against small modifications to the template file.

Upvotes: 3

Related Questions