0

This is for my setup repo which I use in fresh linux installs and company provided macbooks. I have this makefile target:

omz-theme:
    sed -i 's/ZSH_THEME=".*"/ZSH_THEME="$(THEME)"/g' $(HOME)/.zshrc

This works fine on linux but breaks on macs because they use BSD's sed. I need some way to find and replace text in my .zshrc that will run regardless of the system. Almost all resources online point only to sed.

Edit: This is how it "breaks" on mac. Doesn't happen if I do brew install gnu-sed and change the target to use gsed

sed: 1: "/Users/username/.zshrc": unterminated substitute pattern

  • How does it break, exactly? (Please [edit] your question to explain). Does it work if you simply use `sed -i '' ...`? – Jeff Schaller May 19 '22 at 11:35
  • 1
    The "unterminated substitute pattern" error is not a reason you can't use sed, it's a reason you can't use `/` in your sed expression. If you use something like `@` that doesn't exist in your filename it'll be fine. – Charles Duffy May 20 '22 at 18:44
  • 1
    ...that said, for a very good general-purpose reference with a number of options that don't use `sed`, see [BashFAQ #21](https://mywiki.wooledge.org/BashFAQ/021) – Charles Duffy May 20 '22 at 18:46

1 Answers1

1

You can use awk for find and replace as well. Here's a resource with more detail..

For example, your makefile command could be replaced with:

omz-theme:
    awk -v var="ZSH_THEME=$(echo THEME)" '{sub(/^ZSH_THEME=.*$/, var); print}' $(HOME)/.zshrc

You could use this to overwrite the existing $(HOME)/.zshrc file using redirection:

omz-theme:
    awk -v var="ZSH_THEME=$(echo THEME)" '{sub(/^ZSH_THEME=.*$/, var); print}' $(HOME)/.zshrc > $(HOME)/.zshrc

Alternately, you could check the OS using OSTYPE and then use the correct sed syntax for BSD and GNU:

omz-theme:
    if [[ "$OSTYPE" == "linux-gnu"* ]]; then 
        sed -i 's/ZSH_THEME=".*"/ZSH_THEME="$(THEME)"/g' $(HOME)/.zshrc
    else
        sed -i '' 's/ZSH_THEME=".*"/ZSH_THEME="$(THEME)"/g' $(HOME)/.zshrc
    fi

(note: I didn't test the above, but you get the idea)

logyball
  • 158
  • 1
  • 6