5

I want to enable some configurations only when the distribution is Fedora. Here is my code.

let s:os = system("sed -n 's/^NAME=\(.*\)/\1/p' /etc/os-release") echo s:os if s:os == "Fedora" " some configurations endif 

This snippet doesn't work and the s:os is an empty string. However, the sed command works well when I run it in shell directly. I don't know why it doesn't work in vimrc.

1
  • 4
    Double all backslashes or switch to using single-quoted strings. Commented Dec 24, 2019 at 14:33

2 Answers 2

2

The trouble you're having is with the backslashes inside the string (as @Matt correctly pointed out in the comments.)

Vim strings (using double-quotes as delimiters) interpret the backslash as a special character, so you need to escape them with an additional backslash if you want to use them in a double-quoted string.

let s:os = system("sed -n 's/^NAME=\\(.*\\)/\\1/p' /etc/os-release") 

Alternatively, you might want to use single-quoted strings in Vim, since those do not treat the backslash as special and don't require escaping it. This is pretty fine in this particular case, since using double-quotes for the sed expression in the shell command is OK, since they do not contain any shell metacharacters such as $:

let s:os = system('sed -n "s/^NAME=\(.*\)/\1/p" /etc/os-release') 

On the other hand, you could actually do that same operation using Vimscript primitives only, which should be more efficient (since you're not spawning a couple of external processes anymore) and more portable (since it doesn't depend on which particular shell you're using or whether a sed can even be found in $PATH.)

Consider using the following snippet instead:

let s:os = matchlist(readfile('/etc/os-release'), '^NAME=\(.*\)')[1] 

See :help readfile() and :help matchlist().

You might want to add some error handling, in case the file doesn't exist or the variable match can't be found there.

3

@Matt is absolutely right; you might use double backslashes:

let s:os = system("sed -n 's/^NAME=\\(.*\\)/\\1/p' /etc/os-release") 

or switch to a single-quoted string:

let s:os = system('sed -n "s/^NAME=\(.*\)/\1/p" /etc/os-release') 

But here's a tidbit: Here documents are also available as of vim 8.1.1362:

let s:command =<< trim END sed -n "s/^NAME=\(.*\)/\1/p" /etc/os-release END let s:os = system(s:command[0]) 

See :help :let-heredoc for more information.

Happy Vimming!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.